本篇將介紹TypeScript的命名空間,並簡單說明一下與模塊的區別。app
在以前的例子裏,有以下一段代碼,經過修改這段代碼來演示命名空間的用法。ide
1 interface Animal { 2 name: string; 3 eat(): void; 4 } 5 6 class Dog implements Animal { 7 name: string; 8 constructor(theName: string) { 9 this.name = theName; 10 } 11 12 eat() { 13 console.log(`${this.name} 吃狗糧。`); 14 } 15 } 16 17 class Cat implements Animal { 18 name: string; 19 constructor(theName: string) { 20 this.name = theName; 21 } 22 23 eat() { 24 console.log(`${this.name} 吃貓糧。`); 25 } 26 }
同Java的包、.Net的命名空間同樣,TypeScript的命名空間能夠將代碼包裹起來,只對外暴露須要在外部訪問的對象。命名空間內的對象經過export關鍵字對外暴露。this
將上面的例子進行修改spa
1 namespace Biology { 2 export interface Animal { 3 name: string; 4 eat(): void; 5 } 6 7 export class Dog implements Animal { 8 name: string; 9 constructor(theName: string) { 10 this.name = theName; 11 } 12 13 eat() { 14 console.log(`${this.name} 吃狗糧。`); 15 } 16 } 17 18 export class Cat implements Animal { 19 name: string; 20 constructor(theName: string) { 21 this.name = theName; 22 } 23 24 eat() { 25 console.log(`${this.name} 吃貓糧。`); 26 } 27 } 28 } 29 30 31 let dog: Biology.Animal; 32 dog = new Biology.Dog('狗狗'); 33 dog.eat();
經過namespace關鍵字聲明命名空間,經過export導出須要在外部使用的對象。在命名空間外部須要經過「徹底限定名」訪問這些對象。prototype
一般狀況下,聲明的命名空間代碼和調用的代碼不在同一個文件裏3d
biology.tscode
1 namespace Biology { 2 export interface Animal { 3 name: string; 4 eat(): void; 5 } 6 7 export class Dog implements Animal { 8 name: string; 9 constructor(theName: string) { 10 this.name = theName; 11 } 12 13 eat() { 14 console.log(`${this.name} 吃狗糧。`); 15 } 16 } 17 18 export class Cat implements Animal { 19 name: string; 20 constructor(theName: string) { 21 this.name = theName; 22 } 23 24 eat() { 25 console.log(`${this.name} 吃貓糧。`); 26 } 27 } 28 }
app.ts對象
1 /// <reference path="biology.ts" /> 2 3 let dog: Biology.Animal; 4 dog = new Biology.Dog('狗狗'); 5 dog.eat();
經過reference註釋引用命名空間,便可經過「徹底限定名」進行訪問。blog
更有甚者,相同的命名空間會聲明在不一樣的文件中ip
1 namespace Biology { 2 export interface Animal { 3 name: string; 4 eat(): void; 5 } 6 }
1 /// <reference path="biology.ts" /> 2 3 namespace Biology { 4 export class Dog implements Animal { 5 name: string; 6 constructor(theName: string) { 7 this.name = theName; 8 } 9 10 eat() { 11 console.log(`${this.name} 吃狗糧。`); 12 } 13 } 14 }
1 /// <reference path="biology.ts" /> 2 3 namespace Biology { 4 export class Cat implements Animal { 5 name: string; 6 constructor(theName: string) { 7 this.name = theName; 8 } 9 10 eat() { 11 console.log(`${this.name} 吃貓糧。`); 12 } 13 } 14 }
1 // app.ts 2 3 /// <reference path="biology.ts" /> 4 /// <reference path="cat.ts" /> 5 /// <reference path="dog.ts" /> 6 7 8 let dog: Biology.Animal; 9 dog = new Biology.Dog('狗狗'); 10 dog.eat(); 11 12 let cat: Biology.Animal; 13 cat = new Biology.Cat('喵星人'); 14 cat.eat();
編譯以後,每個文件都將編譯成對應的一個JavaScript文件,使用時須要將這些文件都引用進來。經過以下命令,能夠將有相同命名空間的文件編譯到一個JavaScript文件中,這樣在引用時只須要一個文件便可。
1 tsc --outFile js\biology.js ts\biology.ts ts\dog.ts ts\cat.ts
將biology.ts、dog.ts、cat.ts編輯到一個JavaScript文件biology.js文件內,編譯後的文件內容以下
1 /// <reference path="biology.ts" /> 2 var Biology; 3 (function (Biology) { 4 var Dog = (function () { 5 function Dog(theName) { 6 this.name = theName; 7 } 8 Dog.prototype.eat = function () { 9 console.log(this.name + " \u5403\u72D7\u7CAE\u3002"); 10 }; 11 return Dog; 12 }()); 13 Biology.Dog = Dog; 14 })(Biology || (Biology = {})); 15 /// <reference path="biology.ts" /> 16 var Biology; 17 (function (Biology) { 18 var Cat = (function () { 19 function Cat(theName) { 20 this.name = theName; 21 } 22 Cat.prototype.eat = function () { 23 console.log(this.name + " \u5403\u732B\u7CAE\u3002"); 24 }; 25 return Cat; 26 }()); 27 Biology.Cat = Cat; 28 })(Biology || (Biology = {}));
在引用命名空間時,能夠經過import關鍵字起一個別名
1 // app.ts 2 3 /// <reference path="biology.ts" /> 4 /// <reference path="cat.ts" /> 5 /// <reference path="dog.ts" /> 6 7 import bio_other = Biology; // 別名 8 9 let dog: bio_other.Animal; 10 dog = new bio_other.Dog('狗狗'); 11 dog.eat(); 12 13 let cat: bio_other.Animal; 14 cat = new bio_other.Cat('喵星人'); 15 cat.eat();
命名空間:代碼層面的歸類和管理。將有類似功能的代碼都歸一到同一個空間下進行管理,方便其餘代碼引用。更多的是側重代碼的複用。
模塊:一個完整功能的封裝,對外提供的是一個具備完整功能的功能包,須要顯式引用。一個模塊裏可能會有多個命名空間。