# 命名空间

在 JavaScript 中,命名空间能有效的避免全局污染。在 es6 引入了模块系统之后,命名空间就很少被使用了。但 TS 中依然实现了这个特性,尽管在模块系统中,我们不必考虑全局污染情况,但如果使用了全局的类库,命名空间仍然是一个比较好的解决方案。

# 例子

首先创建两个 ts 文件,分别为 a.tsb.ts 代码如下:

本篇大部分为代码段,可以点击查看源码运行阅读。

// ./src/a.ts

namespace Shape {
  const pi = Math.PI
  export function cricle (r: number) {
    return pi * r ** 2
  }
}

如果让成员在全局可见,需要使用 export 关键字输出。

// ./src/b.ts

namespace Shape {
  export function square (x: number) {
    return x * x
  }
}

console.log(Shape.cricle(1))
console.log(Shape.square(1))

同样在 b.ts 文件中也声明了命名空间,在底部调用了 Shape.cricleShape.square 两个方法。

这时我们进行编译的话,因为 cricle 属性存在于 a.ts 文件内,会报出 error TS2339: Property 'cricle' does not exist on type 'typeof Shape'. 错误,这里我们可以使用三斜线指令

# 三斜线指令

三斜线指令是包含单个XML标签的单行注释。 注释的内容会做为编译器指令使用。

三斜线指令仅可放在包含它的文件的最顶端。 一个三斜线指令的前面只能出现单行或多行注释,这包括其它的三斜线指令。 如果它们出现在一个语句或声明之后,那么它们会被当做普通的单行注释,并且不具有特殊的涵义。

/// <reference path="..." /> 指令是三斜线指令中最常见的一种。 它用于声明文件间的 依赖。

三斜线引用告诉编译器在编译过程中要引入的额外的文件。

/// <reference path="a.ts" />

namespace Shape {
  export function square (x: number) {
    return x * x
  }
}

console.log(Shape.cricle(1))
console.log(Shape.square(1))

我们在执行一下打包命令 tsc ./src/b.ts 会生成 a.jsb.js 两个文件。

// ./src/a.js

var Shape;
(function (Shape) {
    var pi = Math.PI;
    function cricle(r) {
        return pi * Math.pow(r, 2);
    }
    Shape.cricle = cricle;
})(Shape || (Shape = {}));

// ./src/b.js

/// <reference path="a.ts" />
var Shape;
(function (Shape) {
    function square(x) {
        return x * x;
    }
    Shape.square = square;
})(Shape || (Shape = {}));
console.log(Shape.cricle(1));
console.log(Shape.square(1));

命名空间在编译之后其实就是一个闭包。

为了实现全局引用效果,我们用 script 标签引入两个文件。

console.log(Shape.cricle(1)) // 3.141592653589793
console.log(Shape.square(1)) // 1

为了调用方便,我们可以为方法设置别名。

// 别名
import cricle = Shape.cricle
console.log(cricle(2)) // 12.566370614359172

注意这里的 import 关键字并不是 es6 中的 import

Last Updated: 11/7/2019, 10:33:05 AM