一,前言

在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

typeScript怎么初始化一个对象为空数据_模块化

报错原因:由于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的命名空间是对全局变量时代的兼容
在一个完全的模块化系统中,可以不必使用命名空间