在我努力编写干净的Javascript代码作为初学者时,我最近在阅读本段时阅读this article关于JavaScript中的命名空间:
下一个示例最顶部的代码演示了在定义变量(对象命名空间)之前可以检查变量(对象命名空间)的不同方式。您通常会看到使用选项1的开发人员,但选项3和5可能会被认为是更彻底的,选项4被认为是一个很好的最佳实践。
<img src="{{ question.image.url }}">
选项1 肯定是我见过的大部分时间,我理解得很清楚。
选项2 很好,但似乎事先缺少// This doesn't check for existence of 'myApplication' in
// the global namespace. Bad practice as you can easily
// clobber an existing variable/namespace with the same name
var myApplication = {};
/*
The following options *do* check for variable/namespace existence.
If already defined, we use that instance, otherwise we assign a new
object literal to myApplication.
Option 1: var myApplication = myApplication || {};
Option 2 if(!MyApplication) MyApplication = {};
Option 3: var myApplication = myApplication = myApplication || {}
Option 4: myApplication || (myApplication = {});
Option 5: var myApplication = myApplication === undefined ? {} : myApplication;
*/
或var myApplication
,否则如果if(!window.myApplication)
不在全局范围内{{1}会抛出错误,不会吗?
选项3 是我遇到的问题:我的理解是首先执行myApplication
,在全局范围内if(!myApplication)
执行(由于{{ 1}}在开始时)。我的问题是,我无法想到这个选项除了选项1之外还有什么功能。
选项4 可以更好地编写myApplication = myApplication
,以避免在myApplication
不在全球范围内时抛出错误。
选项5 排除var
以外的false-y值,但这是个好主意吗?如果window.myApplication || (myApplication = {})
表示空字符串,则其余代码可能会失败,不是吗?
是否有人能够阐明不同选项之间的差异,特别是解释为什么选项3被描述为更彻底?
答案 0 :(得分:54)
如果文章声称选项3“更彻底”,那就不正确了。根本没有指向任务链的中间部分。
是否有人能够阐明不同选项之间的差异,特别是解释为什么选项3被描述为更彻底?
首先,需要注意的是:在2018年,您可能不想使用其中任何一种。相反,使用适当的模块,通过各种模块定义语法之一(AMD,CommonJS,RequireJS)和相关工具,或通过带有import
的ES2015 +模块和export
(可能是相关工具,例如Babel,也许Webpack或Browserify,尽管当前版本的Chrome,Safari和Edge本身支持模块,而Firefox则支持目前在旗帜后面。)
为什么
var x = x = x || {}
比var x = x || {}
更彻底?
不是。
选项2 很好,但似乎事先缺少
var myApplication
或if(!window.myApplication)
,否则如果myApplication
不在全局范围内{{1}会抛出错误,不是吗?
是。 (假设生产发生在全局范围。如果它不在全局范围内,并且当前范围链中的任何位置都有范围内if(!myApplication)
,它将不会抛出,因为myApplication
将不是未解决的符号。)
选项3 是我遇到的问题:我的理解是首先执行
myApplication
,在全局范围内myApplication = myApplication
执行(由于{{ 1}}在开始时)。我的问题是,我不能想到这个选项除了选项1之外还做什么的情况。
不,如果你有
myApplication
这是事情发生的顺序:
var
创建全局(如果它尚不存在),如果不存在则保持不变var myApplication = myApplication = myApplication || {}
并获取var myApplication
中的值(如果它是真实的)或myApplication || {}
(如果不是);我们称之为myApplication
{}
(中间的那个),结果为value1
myApplication = value1
(左边的那个)再次无缘无故地再次执行我认为选项4 可以更好地编写
value1
,以避免在myApplication = value1
不在全球范围内时抛出错误。
确实
选项5 排除
window.myApplication || (myApplication = {})
以外的false-y值,但这是个好主意吗?如果myApplication
表示空字符串,则其余代码可能会失败,不是吗?
是