了解 JavaScript 命名空间

Understanding JavaScript Namespaces

提问人:Phil Catterall 提问时间:4/8/2022 更新时间:4/8/2022 访问量:307

问:

我正在尝试提高我的游戏水平,学习并希望采用有关命名空间的最佳实践,以将我的代码与函数名称、变量等的潜在重叠分开。 我遇到了几种实现这一点的机制,但有一件事让我感到困惑。 许多方法初始化全局 Namespace 变量,如下所示:var ns1 = ns1 || {};

所以这说“如果 ns1 存在,请使用它,否则创建一个新变量”。但是,如果在该变量中,我创建了第二个具有重复名称的函数,它将替换原始函数。我这里有一个 JSFidle。 让我感到困惑的是:为什么要在全局变量赋值中使用“或”? 由于我们试图将事情分开,这对我来说没有意义。我在这里错过了一些基本的东西吗?

或者它是否像我可能有多个库一样简单,所以我正在重用我自己的变量。在这种情况下,我应该确保“ns1”实际上是更独特的东西,从而减少冲突的可能性? 对不起,如果这似乎是一个愚蠢的问题,但我只是担心我错过了一些东西,并想做正确的事情。也许其他人和我的情况一样感到困惑,这可能会有所帮助。谢谢。

JavaScript 命名空间

评论

0赞 Pellay 4/8/2022
这是为了让您以后可以扩展自己的命名空间,例如附加组件或增强功能,这是一组新的功能,可以合并到您现有的 ns1 命名空间中或独立使用。像 jQuery 和 jQuery.ui 一样,它们仍然使用 $ 命名空间

答:

1赞 Bergi 4/8/2022 #1

var ns1声明变量,该变量始终存在。 旨在“使用空对象初始化变量,除非它已经有一个值”。这意味着允许运行多个脚本,这些脚本都以任意顺序使用相同的命名空间。参见 “var FOO = FOO ||{}“(为该变量分配一个变量或一个空对象)在 Javascript 中是什么意思?var myObj = myObj ||{ } 当 myObj 已经存在时?了解详情。ns1 = ns1 || {}

不知道加载了哪些模块可能不是最佳实践,但这种模式已经变得很普遍,并且对错误的恢复能力从来都不是坏事。主要用例是拥有一个包含许多模块的大型应用程序,其中一些模块是可选的或延迟加载的,所有模块都使用应用程序的全局共享命名空间。然后,他们将为其中的各个部分创建子命名空间(嵌套对象),而不是将所有方法放在全局命名空间上。

在编写一个无论如何都将作为单个文件提供的库时,您不需要这样做。对于库作者来说,这是防止库(或其不同版本)被意外多次包含的情况的一种预防措施。

在现代 Web 开发中很少需要这种模式,在现代 Web 开发中,您将使用声明式 ES6 模块。它们中的每一个都有自己的作用域,模块之间的通信不会像脚本那样通过全局作用域发生。

评论

0赞 Phil Catterall 4/8/2022
非常感谢。看来我现在也应该去学习“声明式 ES6 模块”了!
1赞 bob 4/8/2022 #2
var ns1 = ns1 || {};

这意味着如果 ns1 存在,请使用它,否则将其设置为新的“干净的石板”对象。

又名“使用或建立”。

编写相同逻辑的另一种方法是:

if(typeof ns1 != 'undefined') {
    var ns1 = {};
} else {
    var ns1 = ns1;
}

...但以上只是为了说明逻辑。

因此,我们希望将应用程序放置在它自己的上下文(也称为命名空间)中,以便您的所有变量、函数和内容都不会全部混淆并纠缠到本机内容(和/或其他应用程序)中。

因此,这个“干净的石板”对象是“你的空间”或“你的上下文”。你可以把你所有的东西都内置进去。

选择命名空间名称至关重要,应选择冲突可能性较低的名称。

当您想要将应用拆分为多个不同的文件时,此模式会有所帮助。由于可能不清楚哪个 JS 文件最先加载,因此 ns1 ||{} 允许您的任何应用文件成为负责建立“您的空间”的文件。

当 JS 文件加载时,每个文件都会做同样的事情来查看“ns1”是否已经建立......如果没有,请继续建立它。

在网页中运行的 Web 应用中,可用于所有内容(包括默认/浏览器 javascript)的最低级别对象是“window”。

当你写的时候:

var ns1 = "foo"

...您实际上是在窗口上创建一个新变量,因此这与执行以下操作相同:

window.ns1 = "bob"

所以要澄清写ns1的“漫长路要走”||{} 将是:

if( ! window.ns1 ) {
    window.ns1 = {};
}

做与上述完全相同的事情的“捷径”是:

window.ns1 = window.ns1 || {}

...它的目的是建立“你的空间”,如果它还没有这样做的话。

最后,现在你已经建立了“你的空间”或“你的命名空间”,你可以开始构建它并添加到它,如下所示:

window.ns1 = window.ns1 || {}
window.ns1.main = window.ns1.main || {}
window.ns1.main.init = function(){
    //do something   
}
window.ns1.main.someVar = "abc";

如果其他 JS 文件使用 ns1 ||{} 检查/建立。

有很多模式可以构建你的应用程序,这只是试图暴露关键思想。