一,前言
在js中,爲了避免對全局的污染,可以使用命名空間,
在模塊化被廣泛使用後,命名空間就很少被使用了
上一篇介紹了TS的模塊化,雖然在模塊中不再及需要考慮全局污染的問題
但如果使用了全局類庫,仍需要使用命名空間
本篇介紹TS的命名空間
二,命名空間的定義
使用namespace關鍵字聲明TS命名空間
在命名空間內可定義任意變量,僅能在命名空間下可見
如果要使命名空間內的變量全局可見,需要使用export關鍵字導出
namespace.ts
// 命名空間
namespace Shape {
const pi = Math.PI
// 全局可見
export function cricle(r: number){
return pi * r ** 2
}
}
二,命名空間的拆分
隨着命名空間的增大,命名空間也是可以進行拆分的
namespace2.ts
namespace2.ts中有一個和namespace.ts同名的命名空間
namespace Shape {
export function square(x: number){
return x * x
}
}
這樣,相當於一個命名空間分佈在兩個ts文件中,共享一個命名空間
三,命名空間的使用
直接使用命名空間名稱進行訪問即可
namespace2.ts
// 命名空間
namespace Shape {
export function square(x: number){
return x * x
}
}
console.log(Shape.cricle(1)) // namespace1.ts
console.log(Shape.square(1)) // namespace2.ts
注意:
命名空間和模塊不要混用,
不要在一個模塊中使用命名空間,最好在全局使用]
使用方法:
將命名空間的ts文件,編譯成爲js文件,在index.html中引入
將ts文件編譯成js文件:
tsc ./src/namespace2.ts
報錯原因:由於cricle方法在namespace.ts中定義,namespace2.ts中找不到
namespace2.ts引用namespace.ts
使用三斜線指令: /// <reference path="引用文件的相對路徑">
/// <reference path="namespace.ts"/>
// 命名空間
namespace Shape {
export function square(x: number){
return x * x
}
}
console.log(Shape.cricle(1)) // namespace1.ts
console.log(Shape.square(1)) // namespace2.ts
重新執行命令,生成namespace.js和namespace2.js文件
namespace.js:
// 命名空間
var Shape;
(function (Shape) {
var pi = Math.PI;
// 全局可見
function cricle(r) {
return pi * Math.pow(r, 2);
}
Shape.cricle = cricle;
})(Shape || (Shape = {}));
namespace2.js:
/// <reference path="namespace.ts"/>
// 命名空間
var Shape;
(function (Shape) {
function square(x) {
return x * x;
}
Shape.square = square;
})(Shape || (Shape = {}));
console.log(Shape.cricle(1)) // namespace1.ts
console.log(Shape.square(1)) // namespace2.ts
命名空間的實現原理:
命名空間被編譯成了一個立即執行函數,函數創建了一個閉包
在閉包中的私有成員,就是未導出成員
導出成員會被掛載在一個全局變量下
在src/tpl/index.html中引入js文件:
...
<body>
<div class="app"></div>
<script src="src/namespace.js"></script>
<script src="src/namespace2.js"></script>
</body>
...
輸出結果:
3.141592653589793
1
四,命名空間的成員別名
如上,在訪問命名空間的成員時,需要加上命名空間的名稱,如Shape
爲了簡便,也可以爲命名空間成員設置別名,直接訪問
// 爲命名空間成員設置別名
import cricle = Shape.cricle
console.log(cricle(1))
五,結尾
命名空間本質上就是一個閉包,用來隔離作用域
TS的命名空間是對全局變量時代的兼容
在一個完全的模塊化系統中,可以不必使用命名空間