购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

3.5 TypeScript的命名空间

命名空间是一种在命名容器的层次结构中组织代码和声明的机制。

命名空间具有命名成员,每个成员表示值、类型、命名空间或它们的组合,并且这些成员可以是本地成员或导出成员。

命名空间的主体对应于执行一次的函数,从而提供用于保持局部状态并确保隔离的机制。命名空间可以被认为是“立即调用的函数表达式(IIFE)模式的形式化”。

提示:

命名空间可以被简单地理解为类似于Java的包。

在TypeScript中,使用命名空间(关键字“namespace”)来组织管理代码。

3.5.1 声明命名空间

命名空间可以是实例化的,也可以是非实例化的。

● 非实例化的命名空间是仅包含接口类型、类型别名及其他非实例化命名空间的命名空间。

● 实例化的命名空间是不符合此定义的命名空间。

直观地说,实例化的命名空间是为其创建命名空间实例的命名空间,而非实例化的命名空间是不为其生成代码的命名空间。

当命名空间标识符被引用为NamespaceName时,它表示命名空间和类型名称的容器;当命名空间标识符被引用为PrimaryExpression时,它表示命名空间的单实例。

3.5.2 实例5:声明命名空间

以下是一个声明命名空间的例子。

在该例子中,当M作为PrimaryExpression时,表示M具有单个成员a的对象实例;当M作为NamespaceName时,表示M具有单个类型成员P的容器。

示例中的最后一行是错误的,因为m是一个无法在类型名称中引用的变量。

如果上面的M声明排除了导出的变量a,那么M将是一个非实例化的命名空间,将M作为PrimaryExpression引用是错误的。

指定具有多个标识符的IdentifierPath的命名空间声明等同于一系列嵌套的单标识符命名空间声明,其中,除最外层外的所有标识符都自动导出。例如:

等同于:

3.5.3 命名空间体

命名空间体对应于执行一次已初始化命名空间实例的函数。

3.5.4 导入别名声明

可以导入别名声明,用于为其他命名空间中的实体创建本地别名。

由单个标识符组成的EntityName被解析为NamespaceName,因此需要引用命名空间。生成的本地别名引用给定的命名空间,并且本身被归类为命名空间。

由多个标识符组成的EntityName被解析为NamespaceName,后跟一个标识符,该标识符指定给定命名空间中的导出实体。生成的本地别名具有引用实体的所有含义。实际上,就好像导入的实体是使用本地别名在本地声明的一样。

3.5.5 实例6:导入别名声明

以下是一个导入别名声明的例子。

在B中,Y仅仅是命名空间A的别名,而不是本地接口A的别名;而Z是A.X的别名。

如果EntityName的NamespaceName部分引用实例化的命名空间,则在评估为表达式时,NamespaceName需要引用命名空间实例。观察下面这个例子。

YY是非实例化命名空间AA的本地别名。如果更改AA的声明,使得AA成为实例化的命名空间(例如,通过在AA中包含变量声明),则BB中的import语句将是一个错误,因为表达式AA不是引用命名空间AA的命名空间实例。

当import语句包含export修饰符时,将导出本地别名的所有含义。

3.5.6 导出声明

可以导出声明,以便从外部访问命名空间成员。任何声明(如变量、函数、类、类型别名或接口)都能够通过添加关键字“export”来导出。

命名空间的导出声明空间的成员构成了命名空间的导出成员集。命名空间的实例类型是一种对象类型,其命名空间的导出成员集中的每个成员都有一个属性,表示一个值。

导出的成员依赖于(可能为空)一组命名类型。这些命名类型必须至少与导出的成员一样可被访问,否则会发生错误。以下是一个导出声明的例子。

3.5.7 合并声明

命名空间是“开放式”的,具有相对于公共根的相同限定名称的命名空间声明可以合并为单个命名空间。由于命名空间同时创建了命名空间和值,因此我们需要了解它们是如何合并的。

如果要合并命名空间,则要求在每个命名空间中声明的导出接口的类型定义本身已合并,形成一个内部具有合并接口定义的命名空间。

如果要合并命名空间值,假设已经存在具有给定名称的命名空间,则通过获取现有命名空间并将第二个命名空间的导出成员添加到第一个命名空间,来进一步扩展它。

3.5.8 实例7:合并声明

观察以下合并声明的例子。

该例子等价于合并后的声明。

这种命名空间的合并非常容易理解。但是,我们还是需要了解非导出成员的行为是否会发生变化。非导出成员仅在原始(未合并)命名空间中可见。这意味着在,在合并之后,来自其他声明的合并成员无法看到未导出的成员。在下面这个例子中,可以更清楚地看到这一点。

由于未导出hasMuscles,因此,只有共享相同未合并命名空间的animalsHaveMuscles()函数才能看到该成员。即使doAnimalsHaveMuscles()函数是合并的Animal命名空间的一部分,也无法看到此未导出的成员。 Lm/obUVn3At8h9df6TXkZkiPFDpzEQyJIvtUDjGsQSgsQK0IGIkP8snfk4MViA38

点击中间区域
呼出菜单
上一章
目录
下一章
×