我对JavaScript中的范围和闭包的概念有了很好的把握。
此外,以下站点提供了如何实现JavaScript命名空间的示例:
我仍然不明白的是,有多少人似乎混淆了范围和命名空间的概念。此外,同样的人也经常提到一个人不应该如何污染全球命名空间"而不是"在全球范围内创建全局变量/变量"。
问题
let
/ const
)bar
创建新的命名空间是否正确,避免污染全局命名空间(foo
除外),但bar
仍然在全局范围:var foo = { bar: 42 }
答案 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
中引用它们的目的。