JavaScript:命名空间与范围

时间:2018-04-30 12:13:48

标签: javascript scope namespaces

我对JavaScript中的范围和闭包的概念有了很好的把握。

此外,以下站点提供了如何实现JavaScript命名空间的示例:

  1. Everything you wanted to know about JavaScript scope
  2. Namespacing in JavaScript
  3. 我仍然不明白的是,有多少人似乎混淆了范围和命名空间的概念。此外,同样的人也经常提到一个人不应该如何污染全球命名空间"而不是"在全球范围内创建全局变量/变量"。

    问题

    • 范围和命名空间是两个完全不同的概念是不正确的?
      • 命名空间:对代码进行分组,使组内的名称是唯一的,不会与其他名称空间中的类似名称冲突
      • 范围:定义变量的可访问性。 JavaScript有两个范围,全局和本地/功能范围(ES 2015引入了块范围let / const
    • 以下对象文字为bar创建新的命名空间是否正确,避免污染全局命名空间(foo除外),但bar仍然在全局范围:var foo = { bar: 42 }
    • 说"不创建全局变量是不错的,这样就不会污染全局命名空间"?全局vs局部变量(范围)与命名空间不同。如图所示,完全可以屏蔽新命名空间中的变量,并且仍然将其置于全局范围内。
    • 如果避免污染全局命名空间是我们不应该创建全局变量的唯一原因,仅仅创建新的命名空间并且仍然保持全局吗?

1 个答案:

答案 0 :(得分:0)

  

范围和命名空间是两个完全不同的概念是不正确的?

我不会说范围和命名空间完全不相关。如果我们采用“namespace”的字面含义,它就是space不同的名称 - 唯一且不会与其他空格中的名称冲突,如你所说。

在这方面,范围肯定会形成名称空间 - 变量名称是不同的,不会与其他范围的名称冲突。但是,范围是内部的,不能从外部访问,因此组织事物并不是特别有趣。

对象也形成名称空间 - 属性名称是不同的,不会与其他对象上的名称冲突。这就是为什么对象用于将代码结构化为模块的原因,这就是JavaScript中“命名空间”的传统含义。

  

以下对象文字为bar创建新的命名空间是否正确,避免污染全局命名空间(foo除外),但bar仍然在全局范围:var foo = { bar: 42 }

不,bar不是全球范围的成员。这是某个对象的属性。

  

说“不创建全局变量以便不污染全局命名空间”是不是错了?全局vs局部变量(范围)与命名空间不同。

全局变量在JS中有点特殊:它们既是全局对象的属性,也是全局范围中的变量。这就是为什么我们谈论“全局命名空间”以包含所有 - 并且特别强调名称不得相互冲突。

  

如果避免污染全局命名空间是我们不应该创建全局变量的唯一原因,仅仅创建新的命名空间并且仍然保持全局吗?

在上面的示例中创建名称空间(如{bar: 42})仍会创建全局变量:foo。它只创建更少的变量 - 每个模块一个。它还创建了一个特定的命名约定,即全局变量应引用模块而不是普通变量。我们不会使用var i, increment, decrement;而是var counter = {i: …, increment(){…}, decrement(){…}};,并在名称counter中引用它们的目的。