为什么var x = x = x || {}比var x = x ||更彻底{}?

时间:2018-04-16 08:03:31

标签: javascript namespaces

在我努力编写干净的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被描述为更彻底?

1 个答案:

答案 0 :(得分:54)

如果文章声称选项3“更彻底”,那就不正确了。根本没有指向任务链的中间部分。

  

是否有人能够阐明不同选项之间的差异,特别是解释为什么选项3被描述为更彻底?

首先,需要注意的是:在2018年,您可能不想使用其中任何一种。相反,使用适当的模块,通过各种模块定义语法之一(AMDCommonJSRequireJS)和相关工具,或通过带有import的ES2015 +模块和export(可能是相关工具,例如Babel,也许WebpackBrowserify,尽管当前版本的Chrome,Safari和Edge本身支持模块,而Firefox则支持目前在旗帜后面。)

  

为什么var x = x = x || {}var x = x || {}更彻底?

不是。

  

选项2 很好,但似乎事先缺少var myApplicationif(!window.myApplication),否则如果myApplication不在全局范围内{{1}会抛出错误,不是吗?

是。 (假设生产发生在全局范围。如果它不在全局范围内,并且当前范围链中的任何位置都有范围内if(!myApplication),它将不会抛出,因为myApplication将不是未解决的符号。)

  

选项3 是我遇到的问题:我的理解是首先执行myApplication,在全局范围内myApplication = myApplication执行(由于{{ 1}}在开始时)。我的问题是,我不能想到这个选项除了选项1之外还做什么的情况。

不,如果你有

myApplication

这是事情发生的顺序:

  1. var创建全局(如果它尚不存在),如果不存在则保持不变
  2. 评估
  3. var myApplication = myApplication = myApplication || {} 并获取var myApplication中的值(如果它是真实的)或myApplication || {}(如果不是);我们称之为myApplication
  4. 执行
  5. {}(中间的那个),结果为value1
  6. myApplication = value1(左边的那个)再次无缘无故地再次执行
  7.   我认为

    选项4 可以更好地编写value1,以避免在myApplication = value1不在全球范围内时抛出错误。

    确实

      

    选项5 排除window.myApplication || (myApplication = {})以外的false-y值,但这是个好主意吗?如果myApplication表示空字符串,则其余代码可能会失败,不是吗?