TypeScript基礎入門之模塊(一)

轉發(fā) # TypeScript基礎入門之模塊(一)

模塊

關于術語的一點說明: 請務必注意一點,TypeScript 1.5里術語名已經發(fā)生了變化。 "內部模塊"現(xiàn)在稱做"命名空間"。 "外部模塊"現(xiàn)在則簡稱為"模塊",這是為了與 ECMAScript 2015里的術語保持一致,(也就是說 module X { 相當于現(xiàn)在推薦的寫法 namespace X {)。

介紹

從ECMAScript 2015開始,JavaScript引入了模塊的概念。TypeScript也沿用這個概念。

模塊在其自身的作用域里執(zhí)行,而不是在全局作用域里;這意味著定義在一個模塊里的變量,函數(shù),類等等在模塊外部是不可見的,除非你明確地使用export形式之一導出它們。 相反,如果想使用其它模塊導出的變量,函數(shù),類,接口等的時候,你必須要導入它們,可以使用import形式之一。

模塊是自聲明的;兩個模塊之間的關系是通過在文件級別上使用imports和exports建立的。

模塊使用模塊加載器去導入其它的模塊。 在運行時,模塊加載器的作用是在執(zhí)行此模塊代碼前去查找并執(zhí)行這個模塊的所有依賴。 大家最熟知的JavaScript模塊加載器是服務于Node.js的 CommonJS和服務于Web應用的Require.js。

TypeScript與ECMAScript 2015一樣,任何包含頂級import或者export的文件都被當成一個模塊。相反地,如果一個文件不帶有頂級的import或者export聲明,那么它的內容被視為全局可見的(因此對模塊也是可見的)。

導出

導出聲明

任何聲明(比如變量,函數(shù),類,類型別名或接口)都能夠通過添加export關鍵字來導出。

Validation.ts

export interface StringValidator {
  isAcceptable(s: string): boolean;
}

ZipCodeValidator.ts

export const numberRegexp = /^[0-9]+$/;

export class ZipCodeValidator implements StringValidator {
  isAcceptable(s: string): boolean {
    return s.length === 5 && numberRegexp.test(s);
  }
}

導出語句

導出語句很便利,因為我們可能需要對導出的部分重命名,所以上面的例子可以這樣改寫:

export const numberRegexp = /^[0-9]+$/;

class ZipCodeValidator implements StringValidator {
  isAcceptable(s: string): boolean {
    return s.length === 5 && numberRegexp.test(s);
  }
}

export { ZipCodeValidator };
export { ZipCodeValidator as mainValidator }

重新導出

我們經常會去擴展其它模塊,并且只導出那個模塊的部分內容。 重新導出功能并不會在當前模塊導入那個模塊或定義一個新的局部變量。
ParseIntBasedZipCodeValidator.ts

export class ParseIntBasedZipCodeValidator {
  isAcceptable(s: string): boolean {
    return s.length === 5 && parseInt(s).toString() === s;
  }
}

export { ZipCodeValidator as RegExpBaseZipCodeValidator } from './ZipCodeValidator';

或者一個模塊可以包裹多個模塊,并把他們導出的內容聯(lián)合在一起通過語法:export * from "module"。

AllValidators.ts

export * from "./StringValidator"; // exports interface 'StringValidator'
export * from "./ZipCodeValidator";  // exports class 'ZipCodeValidator'

導入

模塊的導入操作與導出一樣簡單。 可以使用以下import形式之一來導入其它模塊中的導出內容。

導入一個模塊中的某個導出內容

import { ZipCodeValidator } from "./ZipCodeValidator";

let myValidator = new ZipCodeValidator();

可以對導入內容重命名

import { ZipCodeValidator as ZCV } from "./ZipCodeValidator";
let myValidator = new ZCV();

將整個模塊導入到一個變量,并通過它來訪問模塊的導出部分

import * as validator from "./ZipCodeValidator";
let myValidator = new validator.ZipCodeValidator();

具有副作用的導入模塊

盡管不推薦這么做,一些模塊會設置一些全局狀態(tài)供其它模塊使用。 這些模塊可能沒有任何的導出或用戶根本就不關注它的導出。 使用下面的方法來導入這類模塊:

import "./my-module.js";

默認導出

每個模塊都可以有一個default導出。 默認導出使用 default關鍵字標記;并且一個模塊只能夠有一個default導出。 需要使用一種特殊的導入形式來導入 default導出。

default導出十分便利。 比如,像JQuery這樣的類庫可能有一個默認導出 jQuery或,并且我們基本上也會使用同樣的名字jQuery或導出JQuery。

JQuery.d.ts

declare let $: JQuery;
export default $;

App.ts

import $ from "JQuery";

$("button.continue").html( "Next Step..." );

類和函數(shù)聲明可以直接被標記為默認導出。 標記為默認導出的類和函數(shù)的名字是可以省略的。

ZipCodeValidator.ts

export default class ZipCodeValidator {
    static numberRegexp = /^[0-9]+$/;
    isAcceptable(s: string) {
        return s.length === 5 && ZipCodeValidator.numberRegexp.test(s);
    }
}

Test.ts

import validator from "./ZipCodeValidator";

let myValidator = new validator();

或者

StaticZipCodeValidator.ts

const numberRegexp = /^[0-9]+$/;

export default function (s: string) {
    return s.length === 5 && numberRegexp.test(s);
}

Test.ts

import validate from "./StaticZipCodeValidator";

let strings = ["Hello", "98052", "101"];

// Use function validate
strings.forEach(s => {
  console.log(`"${s}" ${validate(s) ? " matches" : " does not match"}`);
});

default導出也可以是一個值
OneTwoThree.ts

export default "123";

Log.ts

import num from "./OneTwoThree";

console.log(num); // "123"

export =import = require()
CommonJS和AMD都有一個exports對象的概念,它包含了一個模塊的所有導出內容。

它們也支持把exports替換為一個自定義對象。 默認導出就好比這樣一個功能;然而,它們卻并不相互兼容。 TypeScript模塊支持 export =語法以支持傳統(tǒng)的CommonJS和AMD的工作流模型。

export =語法定義一個模塊的導出對象。 它可以是類,接口,命名空間,函數(shù)或枚舉。

若要導入一個使用了export =的模塊時,必須使用TypeScript提供的特定語法import module = require("module")。

ZipCodeValidator.ts

let numberRegexp = /^[0-9]+$/;
class ZipCodeValidator {
    isAcceptable(s: string) {
        return s.length === 5 && numberRegexp.test(s);
    }
}
export = ZipCodeValidator;

Test.ts

import zip = require("./ZipCodeValidator");

// 嘗試一些字符
let strings = ["Hello", "98052", "101"];

// 使用validator
let validator = new zip();

// 檢測每個字符串,是否通過驗證
strings.forEach(s => {
  console.log(`"${ s }" - ${ validator.isAcceptable(s) ? "matches" : "does not match" }`);
});
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • 紅龍感覺上好像是數(shù)據,股票數(shù)據。 白風很搞怪。 藍夜很安靜,有種要睡了的感覺。 黃種子好像仙女飄飄,怪優(yōu)雅的。 紅...
    阿B_欣閱讀 294評論 0 0
  • 在林間深處,微風給我擁抱。在溪水流淌的河流中,流水給我擁抱。而我希望在你的面前,你給我擁抱
    清風丶風塵閱讀 301評論 0 0
  • 仰望著眼前高樓大廈車水馬龍它是我的目標,凝視片刻深吸氣奔著目標前進,每個人都有不同的夢想,有夢想就去追求。
    雨馨l(fā)閱讀 155評論 0 1
  • 2012年,我認識了你,在那個滿懷激情又無比悲傷的夏天。 初見你時,我以為你的性格很像我的一個閨蜜,沉靜,內斂,拋...
    暗黑禁衛(wèi)軍閱讀 409評論 0 0

友情鏈接更多精彩內容