提问人:Phil Catterall 提问时间:4/8/2022 更新时间:4/8/2022 访问量:307
了解 JavaScript 命名空间
Understanding JavaScript Namespaces
问:
我正在尝试提高我的游戏水平,学习并希望采用有关命名空间的最佳实践,以将我的代码与函数名称、变量等的潜在重叠分开。
我遇到了几种实现这一点的机制,但有一件事让我感到困惑。
许多方法初始化全局 Namespace 变量,如下所示:var ns1 = ns1 || {};
所以这说“如果 ns1 存在,请使用它,否则创建一个新变量”。但是,如果在该变量中,我创建了第二个具有重复名称的函数,它将替换原始函数。我这里有一个 JSFidle。 让我感到困惑的是:为什么要在全局变量赋值中使用“或”? 由于我们试图将事情分开,这对我来说没有意义。我在这里错过了一些基本的东西吗?
或者它是否像我可能有多个库一样简单,所以我正在重用我自己的变量。在这种情况下,我应该确保“ns1”实际上是更独特的东西,从而减少冲突的可能性? 对不起,如果这似乎是一个愚蠢的问题,但我只是担心我错过了一些东西,并想做正确的事情。也许其他人和我的情况一样感到困惑,这可能会有所帮助。谢谢。
答:
var ns1
声明变量,该变量始终存在。 旨在“使用空对象初始化变量,除非它已经有一个值”。这意味着允许运行多个脚本,这些脚本都以任意顺序使用相同的命名空间。参见 “var FOO = FOO ||{}“(为该变量分配一个变量或一个空对象)在 Javascript 中是什么意思?或 var myObj = myObj ||{ } 当 myObj 已经存在时?了解详情。ns1 = ns1 || {}
不知道加载了哪些模块可能不是最佳实践,但这种模式已经变得很普遍,并且对错误的恢复能力从来都不是坏事。主要用例是拥有一个包含许多模块的大型应用程序,其中一些模块是可选的或延迟加载的,所有模块都使用应用程序的全局共享命名空间。然后,他们将为其中的各个部分创建子命名空间(嵌套对象),而不是将所有方法放在全局命名空间上。
在编写一个无论如何都将作为单个文件提供的库时,您不需要这样做。对于库作者来说,这是防止库(或其不同版本)被意外多次包含的情况的一种预防措施。
在现代 Web 开发中很少需要这种模式,在现代 Web 开发中,您将使用声明式 ES6 模块。它们中的每一个都有自己的作用域,模块之间的通信不会像脚本那样通过全局作用域发生。
评论
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 ||{} 检查/建立。
有很多模式可以构建你的应用程序,这只是试图暴露关键思想。
评论