本篇将介绍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();
命名空间:代码层面的归类和管理。将有类似功能的代码都归一到同一个空间下进行管理,方便其余代码引用。更多的是侧重代码的复用。
模块:一个完整功能的封装,对外提供的是一个具备完整功能的功能包,须要显式引用。一个模块里可能会有多个命名空间。