什么是“var FOO = FOO ||” {}“(分配一个variables或一个空对象的variables)在JavaScript中的意思?

看一个在线源代码,我在几个源文件的顶部看到了这个。

var FOO = FOO || {}; FOO.Bar = …; 

但是我不知道|| {} || {}的确如此。

我知道{}等于new Object() ,我认为|| 就像“如果它已经存在使用它的价值,否则使用新的对象。

为什么我会在源文件的顶部看到这个?

你对|| {}的意图的猜测 || {}非常接近。

当在文件的顶部看到这个特定的模式被用来创build一个命名空间 ,即一个命名对象,在该命名对象下可以创build函数和variables,而不会过度地污染全局对象。

使用它的原因是,如果你有两个(或更多)文件:

 var MY_NAMESPACE = MY_NAMESPACE || {}; MY_NAMESPACE.func1 = { } 

 var MY_NAMESPACE = MY_NAMESPACE || {}; MY_NAMESPACE.func2 = { } 

这两个文件共享相同的命名空间,然后加载这两个文件的顺序无关紧要,您仍然可以正确地在MY_NAMESPACE对象中正确定义func1func2

加载的第一个文件将创build初始MY_NAMESPACE对象,随后加载的任何文件都将增加对象。

有用地,这也允许asynchronous加载共享相同命名空间的脚本,这可以改善页面加载时间。 如果<script>标签设置了defer属性,则无法知道它们将以何种顺序进行解释,如上所述,这也解决了这个问题。

 var AEROTWIST = AEROTWIST || {}; 

基本上这条线是说将AEROTWISTvariables设置为AEROTWISTvariables的值,或者将其设置为空对象。

双pipe|| 是一个OR语句,OR的第二部分只有在第一部分返回false时才被执行。

因此,如果AEROTWIST已经有一个值,它将被保存为该值,但是如果它之前没有被设置,那么它将被设置为空对象。

这和说这个基本一样:

 if(!AEROTWIST) {var AEROTWIST={};} 

希望有所帮助。

||的另一个常见用途 也是为未定义的函数参数设置一个默认值:

 function display(a) { a = a || 'default'; // here we set the default value of a to be 'default' console.log(a); } // we call display without providing a parameter display(); // this will log 'default' display('test'); // this will log 'test' to the console 

其他编程中的等价物通常是:

 function display(a = 'default') { // ... } 

有两个主要部分, var FOO = FOO || {}; var FOO = FOO || {}; 盖子。

#1防止覆盖

想象一下,你的代码被分割成多个文件,而你的同事也在一个名为FOO的对象上工作。 那么可能会导致某人已经定义了FOO并为其分配function(如skateboardfunction)。 那么你会覆盖它,如果你不检查它是否已经存在。

有问题的情况:

 // Definition of co-worker "Bart" in "bart.js" var FOO = {}; FOO.skateboard = function() { alert('I like skateboarding!'); }; // Definition of co-worker "Homer" in "homer.js" var FOO = {}; FOO.donut = function() { alert('I like donuts!'); }; 

在这种情况下,如果您将HTML文件homer.js加载到HTML中的homer.js之后, skateboardfunction将会消失,因为Homer定义了一个新的FOO对象(因此覆盖了来自Bart的现有对象),所以它只知道donutfunction。

所以你需要使用var FOO = FOO || {}; var FOO = FOO || {}; 这意味着“FOO将被分配给FOO(如果它已经存在)或新的空白对象(如果FOO已经不存在)。

解:

 var FOO = FOO || {}; // Definition of co-worker Bart in bart.js FOO.skateboard = function() { alert('I like skateboarding!'); }; // Definition of co-worker Homer in homer.js var FOO = FOO || {}; FOO.donut = function() { alert('I like donuts!'); }; 

由于Bart和Homer现在在定义方法之前检查是否存在FOO ,因此可以按任意顺序加载bart.jshomer.js ,而不必重写彼此的方法(如果它们具有不同的名称)。 所以你总是会得到一个有skateboarddonut (Yay!)的FOO对象。

#2定义一个新的对象

如果你已经阅读了第一个例子,那么你现在已经有了什么用途了 || {}

因为如果没有现有的FOO对象,那么这个OR-case就会变成活动的,并创build一个新的对象,所以你可以给它分配函数。 喜欢:

 var FOO = {}; FOO.skateboard = function() { alert('I like skateboarding!'); }; 

如果AEROTWIST中没有值,或者它是空的或未定义的,则分配给新的AEROTWIST的值将是{}(一个空白对象)

|| 运算符有两个值:

 a || b 

如果一个真的 ,它会返回a 。 否则,它会返回b

谬误值为nullundefined0""NaNfalse 。 真理值是一切。

所以如果a没有被设置(是undefined )它将返回b

请注意,在IE的某些版本中,此代码将无法按预期工作。 因为var ,这个variables被重新定义分配 – 如果我正确地记得这个问题 – 你会最终总是有一个新的对象。 这应该解决这个问题:

 var AEROTWIST; AEROTWIST = AEROTWIST || {};