TypeScript學習筆記(七) - 命名空間


本篇將介紹TypeScript的命名空間,並簡單說明一下與模塊的區別。

在之前的例子里,有如下一段代碼,通過修改這段代碼來演示命名空間的用法。

 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關鍵字對外暴露。

將上面的例子進行修改

 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導出需要在外部使用的對象。在命名空間外部需要通過“完全限定名”訪問這些對象。

 

二、命名空間的引用

通常情況下,聲明的命名空間代碼和調用的代碼不在同一個文件里

biology.ts

 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 }
biology.ts

app.ts

1 /// <reference path="biology.ts" />
2 
3 let dog: Biology.Animal;
4 dog = new Biology.Dog('狗狗');
5 dog.eat();

通過reference注釋引用命名空間,即可通過“完全限定名”進行訪問。

更有甚者,相同的命名空間會聲明在不同的文件中

1 namespace Biology {
2     export interface Animal {
3         name: string;
4         eat(): void;
5     }
6 }
biology.ts
 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 }
dog.ts
 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 }
cat.ts
 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();

 

四、命名空間與模塊

命名空間:代碼層面的歸類和管理。將有相似功能的代碼都歸一到同一個空間下進行管理,方便其他代碼引用。更多的是側重代碼的復用。

模塊:一個完整功能的封裝,對外提供的是一個具有完整功能的功能包,需要顯式引用。一個模塊里可能會有多個命名空間。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM