1. 模塊
模塊的特性
- ES6的模塊自動采用嚴格模式;
- 在ES6模塊中,頂層的this的值是undefined,不應該在頂層代碼使用this;
- export語句輸出的接口與其對應的值是動態綁定關系,即通過該接口,可以獲取到模塊內部實時的值;這一點與CommonJS規范完全不同,CommonJS模塊輸出的是值的緩存,不存在動態更新;
- export 和 import 命令可以并且只能出現在模塊頂層的任意位置;如果export 和 import 命令處于塊級作用域內,就會報錯;這是因為如果export 和 import 命令處于代碼塊之中,就沒法做靜態優化了,違背了ES6模塊的設計初衷;
- 因為:export default命令的本質是:將該命令后面的值,賦給default變量,然后輸出一個叫做default的量;
所以:
- 可以直接將一個值寫在export default之后;
- export default之后不能跟變量聲明語句;
- import后面的from指定模塊文件的位置,可以是相對路徑或者絕對路徑,
.js
后綴也可以省略;如果from后面指定的不是路徑,只是一個模塊名字,那么必須有配置文件能使JavaScript引擎找到該模塊的位置;- import命令具有提升效果,會提升到整個模塊的頂部,首先執行。這種行為的本質是:import命令是編譯階段執行的,所以它會在所有代碼運行之前執行;
- 由于import語句是在編譯階段執行,所以import語句中不能包含表達式、變量等只能在運行時才能得到結果的語法結構;
- 如果有相同的多條import語句,那么只會執行一次同一條import語句;
- 由于 ES6 輸入的模塊變量,只是一個“符號連接”,所以這個變量是只讀的,對它進行重新賦值會報錯;
- 在 Node 環境中,使用import命令加載 CommonJS 模塊,Node 會自動將module.exports屬性,當作模塊的默認輸出,即等同于export default;
- 采用require命令加載 ES6 模塊時,ES6 模塊的所有輸出接口,會成為輸入對象的屬性。
- ES6模塊與CommonJS模塊的區別:
- CommonJS 模塊輸出的是一個值的拷貝,ES6 模塊輸出的是值的引用。
- CommonJS 模塊是運行時加載,ES6 模塊是編譯時輸出接口。
- ES6 模塊之中,頂層的this指向undefined;CommonJS 模塊的頂層this指向當前模塊。
模塊導入和導出的各種寫法
導出
有以下幾種導出方法:
- 導出聲明:
直接在(變量、函數、類型、類型別名、接口)聲明前添加export
關鍵字;
示例如下:export const numberRegexp = /^[0-9]+$/; export class ZipCodeValidator implements StringValidator { isAcceptable(s: string) { return s.length === 5 && numberRegexp.test(s); } }
- 導出語句:
導出語句可以把需要導出的實例一塊導出,也可以對導出的部分重新命名;
示例如下:export const numberRegexp = /^[0-9]+$/; class ZipCodeValidator implements StringValidator { isAcceptable(s: string) { return s.length === 5 && numberRegexp.test(s); } } export { ZipCodeValidator,numberRegexp }; export { ZipCodeValidator as mainValidator };
- 重新導出:
我們經常會去擴展其它模塊,并且只導出那個模塊的部分內容。 重新導出功能并不會在當前模塊導入那個模塊或定義一個新的局部變量;
示例如下:// 導出原先的類但做了重命名 export {ZipCodeValidator as RegExpBasedZipCodeValidator} from "./ZipCodeValidator";
- 默認導出:
每個模塊都可以有一個default導出。 默認導出使用default關鍵字標記;并且一個模塊只能夠有一個default導出。 需要使用一種特殊的導入形式來導入default導出。標記為默認導出的實體可以省略名字;
示例如下:export default function (s: string) { return s.length === 5 && numberRegexp.test(s); }
導入
模塊的導入操作與導出一樣簡單。 可以使用以下import形式之一來導入其它模塊中的導出內容:
- 導入一個模塊中的某個導出內容,也可對于進行重命名::
格式如下:
示例如下:import { 要導出的內容的名字 } from "模塊路徑"; import { 要導出的內容的名字 as 新名字 } from "模塊路徑";
import { ZipCodeValidator as ZCV } from "./ZipCodeValidator"; let myValidator = new ZCV();
- 將整個模塊導入到一個變量,并通過它來訪問模塊的導出部分:
格式如下:
示例如下:import * as 新名字 from "模塊路徑";
import * as validator from "./ZipCodeValidator"; let myValidator = new validator.ZipCodeValidator();
- 導出默認的導出項:
每個模塊都可以有一個default導出。 默認導出使用default關鍵字標記;并且一個模塊只能夠有一個default導出。
導出默認的導郵項目的格式如下:
示例如下:import 自定義名字 from "模塊路徑";
import JQ from "JQuery"; JQ("button.continue").html( "Next Step..." );
- 具有副作用的導入模塊:
格式如下:
此種導入,相當于把相應模塊的代碼插入到了本模塊;import "模塊路徑";
export = 和 import = require()
CommonJS和AMD都有一個exports對象的概念,它包含了一個模塊的所有導出內容。
它們也支持把exports替換為一個自定義對象。 默認導出就好比這樣一個功能;然而,它們卻并不相互兼容。 TypeScript模塊支持export =語法以支持傳統的CommonJS和AMD的工作流模型。
export =語法定義一個模塊的導出對象。 它可以是類,接口,命名空間,函數或枚舉。
若要導入一個使用了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");
// Some samples to try
let strings = ["Hello", "98052", "101"];
// Validators to use
let validator = new zip();
// Show whether each string passed each validator
strings.forEach(s => {
console.log(`"${ s }" - ${ validator.isAcceptable(s) ? "matches" : "does not match" }`);
});
2. 別名
格式:
import 新名字 = x.y.z;
這是一種簡化命名空間操作的方法是使用import q = x.y.z給常用的對象起一個短的名字。 不要與用來加載模塊的import x = require('name')語法弄混了,這里的語法是為指定的符號創建一個別名。 你可以用這種方法為任意標識符創建別名,也包括導入的模塊中的對象。
示如如下:
namespace Shapes {
export namespace Polygons {
export class Triangle { }
export class Square { }
}
}
import polygons = Shapes.Polygons;
let sq = new polygons.Square(); // Same as "new Shapes.Polygons.Square()"
注意:
我們并沒有使用require關鍵字,而是直接使用導入符號的限定名賦值。 這與使用var相似,但它還適用于類型和導入的具有命名空間含義的符號。 重要的是,對于值來講,import會生成與原始符號不同的引用,所以改變別名的var值并不會影響原始變量的值。
3. 函數語法
- 函數類型的表示:
(參數列表)=>返回值類型
- 函數的定義:
function 函數名字(參數列表):返回類型 { 代碼 }
- 箭頭函數的定義:
(參數列表):返回類型=>{ 代碼 }
4. TypeScript語法特性:
- TypeScript的類型注釋是可選的,可有可無;并且TypeScript編譯器具有類型推斷功能;
- 函數的參數列表中的可選參數必須放在必須參數的后面;
- 函數的參數列表中的默認參數值參數不必非得放在必須參數的后面,它可以放在參數列表的任何位置;當默認值參數不是放在必須參數的后面時,用戶必須通過給默認值參數傳入undefined來使用默認值參數的默認值;當默認參值參數放在必須參數后面時,默認值參數是可選的,在調用函數時,可以省略默認值參數;
- 剩余參數必須是數組類型,并且必須放在能數列表中的最后一個;
- 在TypeScript里,類的成員默認為public;
- 只讀屬性必須在聲明時或構造函數里被初始化;
- 使用存取器時,編譯器必須設置為輸出ECMAScript 5或更高;不支持降級到ECMAScript 3;
- 只帶有get不帶有set的存取器自動被推斷為readonly;這在從代碼生成.d.ts文件時是有幫助的,因為利用這個屬性的用戶會看到不允許夠改變它的值;
5. 接口
- 當把對象字面量賦值給變量或作為參數傳遞的時候,該對象字面量不能存在任何“目標類型”(變量類型或者參數類型)不包含的屬性時;
- 對于函數類型的類型檢查來說,函數的參數名不需要與接口里定義的名字相匹配;