JavaScript如果要替名稱加上命名空間,不外乎就是利用物件或是模組來達成。但在TypeScript中,有namespace
關鍵字可以讓我們快速地新增命名空間來用。
namespace
關鍵字的用法很簡單,如下:
namespace 命名空間的名稱(可以用句號連接多個名稱) { 程式敘述區塊 }
若要將namespace
程式區塊中的名稱暴露出來,與模組一樣,是在var
、let
、const
、function
、class
、interface
、enum
、type
關鍵字前加上export
關鍵字。當然,namespace
程式區塊中也還可以再使用namespace
關鍵字來建立程式敘述區塊,且namespace
關鍵字前也是可以加上export
關鍵字來將其暴露的。
例如:
namespace org.magiclen {
export namespace A {
export function f() {
console.log('A');
}
}
export namespace B {
export function f() {
console.log('B');
}
}
export namespace AB {
export function f() {
A.f();
B.f();
}
}
}
org.magiclen.A.f();
org.magiclen.B.f();
org.magiclen.AB.f();
以上程式的輸出結果如下:
A
B
A
B
擴充命名空間
我們可以建立出相同名稱的namespace
程式敘述區塊,替已存在的命名空間擴充原本不存在的名稱。
例如:
namespace org.magiclen {
export namespace A {
export function f() {
console.log('A');
}
}
export namespace A {
export function f2() {
console.log('A');
}
}
export namespace B {
export function f() {
console.log('B');
}
}
export namespace AB {
export function f() {
A.f();
B.f();
}
}
}
namespace org.magiclen.A {
export function ff() {
console.log('AA');
}
}
namespace org.magiclen {
export function f() {
console.log('Hello!');
}
}
org.magiclen.A.f();
org.magiclen.B.f();
org.magiclen.AB.f();
org.magiclen.A.ff();
org.magiclen.f();
命名空間除了可以拿來擴充同名的命名空間之外,也可以拿來擴充同名的變數、常數、函數、類別、介面、列舉和型別別名下的名稱。有點詭異,但十分方便。例如:
type T = number | string;
namespace T {
export let n = 1;
}
console.log(T.n);
function f() {
}
namespace f {
export let s = '2';
}
console.log(f.s);
命名空間的網頁應用
實際編譯以下TypeScript程式:
namespace A {
export function f() {
console.log('A');
}
}
會得到這樣的JavaScript程式:
var A;
(function (A) {
function f() {
console.log('A');
}
A.f = f;
})(A || (A = {}));
A
命名空間實際上在JavaScript中會是一個變數A
。也就是說,利用這樣的性質,我們可以很容易地在網頁瀏覽器上透過命名空間產生的變數,來存取這個變數下的名稱。
舉例來說,現在有以下兩個檔案:
namespace A {
export function f() {
console.log('A');
}
}
namespace B {
export function f() {
console.log('B');
}
}
以上兩個檔案雖然都不是TypeScript模組(因為最外層並沒有使用export
關鍵字),但是它們的f
函數在網頁中並不會有衝突,可以透過全域變數A
和B
來呼叫它們。如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<script src="a.js"></script>
<script src="b.js"></script>
</head>
<body>
<script>
A.f();
B.f();
</script>
</body>
</html>
總結
至此我們已經把TypeScript能夠宣告的名稱類型(變數、常數、函數、類別、介面、列舉、型別別名、模組、命名空間)都學全了。只是有些名稱可以當作型別,有些名稱可以當作值,有些名稱又可以當作命名空間來用,實在很混亂。在此用以下表格做個歸納:
名稱類型 | 命名空間 | 型別 | 值 | 例子 |
---|---|---|---|---|
var | 否 | 否 | 是 | var name = 'MagicLen';
console.log(name); |
let | 否 | 否 | 是 | let name = 'MagicLen';
console.log(name); |
const | 否 | 否 | 是 | const name = 'MagicLen';
console.log(name); |
function | 否 | 否 | 是 | function f() {}
console.log(f); |
class | 否 | 是 | 是 | class C {}
console.log(C);
let o: C = new C(); |
interface | 否 | 是 | 否 | interface I {}
class C implements I {}
let o: I = new C(); |
enum | 否 | 是 | 是 | enum E { // it can not be a const enum
V
}
console.log(E);
let o: E = E.V; |
type | 否 | 是 | 否 | interface I {}
let o: I; |
import | 否 | 否 | 是 | import * as fs from 'fs';
console.log(fs); |
namespace | 是 | 否 | 否 | namespace NS {
export function f() {}
}
NS.f(); |
在下一個章節中,我們要來學習TypeScript的裝飾器(Decorator)。
下一章:裝飾器(Decorator)。
留言