什么是;var FOO=FOO |{};(为该变量指定一个变量或一个空对象)在Javascript中是什么意思?
查看在线源代码时,我在几个源文件的顶部发现了这一点什么是;var FOO=FOO |{};(为该变量指定一个变量或一个空对象)在Javascript中是什么意思?,javascript,namespaces,variable-declaration,or-operator,Javascript,Namespaces,Variable Declaration,Or Operator,查看在线源代码时,我在几个源文件的顶部发现了这一点 var FOO = FOO || {}; FOO.Bar = …; 但是我不知道|{}做什么 我知道{}等于新对象(),我认为|的意思是“如果它已经存在,使用它的值,否则使用新对象” 为什么我会在源文件的顶部看到它?如果AEROTWIST中没有值,或者它为null或未定义,则分配给新AEROTWIST的值将是{}(一个空白对象)操作符采用两个值: a || b 如果a是,它将返回a。否则,它将返回b var AEROTWIST = AERO
var FOO = FOO || {};
FOO.Bar = …;
但是我不知道|{}
做什么
我知道{}
等于新对象()
,我认为|
的意思是“如果它已经存在,使用它的值,否则使用新对象”
为什么我会在源文件的顶部看到它?如果AEROTWIST中没有值,或者它为null或未定义,则分配给新AEROTWIST的值将是{}(一个空白对象)操作符采用两个值:
a || b
如果a是,它将返回a
。否则,它将返回b
var AEROTWIST = AEROTWIST || {};
falsy值是null
,未定义的,0
,“
,NaN
和false
。真实值是其他所有值
因此,如果未设置a
(是否undefined
),它将返回b
var AEROTWIST = AEROTWIST || {};
基本上,这一行的意思是将AEROTWIST
变量设置为AEROTWIST
变量的值,或者将其设置为空对象
双管道|
是OR语句,只有在第一部分返回false时,才会执行OR的第二部分
因此,如果AEROTWIST
已经有一个值,它将被保留为该值,但是如果它以前没有被设置,那么它将被设置为空对象
这基本上和这样说是一样的:
if(!AEROTWIST) {var AEROTWIST={};}
希望有帮助。你对|{}
的意图的猜测非常接近
在文件顶部看到的这种特殊模式用于创建名称空间,即命名对象,在该对象下可以创建函数和变量,而不会过度污染全局对象
之所以使用它,是因为如果您有两个(或更多)文件:
及
这两个文件共享同一名称空间这两个文件的加载顺序无关紧要,但仍然可以在MY_名称空间对象中正确定义func1
和func2
加载的第一个文件将创建初始的MY_NAMESPACE
对象,随后加载的任何文件都将扩展该对象
有用的是,这还允许异步加载共享同一名称空间的脚本,这可以缩短页面加载时间。如果
标记设置了defer
属性,则您无法知道它们的解释顺序,因此如上所述,这也解决了该问题。另一个常见的| |的用法是设置d未定义函数参数的默认值也包括:
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') {
// ...
}
请注意,在某些版本的IE中,此代码无法按预期工作。因为var
,变量被重新定义和分配,因此–如果我正确回忆问题–您将始终拥有一个新对象。这将解决问题:
var AEROTWIST;
AEROTWIST = AEROTWIST || {};
var FOO=FOO | |{};
涵盖了两个主要部分
#1防止覆盖
假设您将代码拆分为多个文件,而您的同事也在处理一个名为FOO
的对象。那么,可能会出现这样的情况:有人已经定义了FOO
并为其分配了功能(如滑板
功能)。然后,如果不检查它是否已存在,您将覆盖它
问题案例:
// 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!');
};
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!');
};
在这种情况下,如果在HTML中的bart.js
之后加载JavaScript文件homer.js
,则skateboard
函数将消失,因为homer定义了一个新的FOO
对象(从而覆盖了来自bart的现有对象),因此它只知道donut
函数
因此,您需要使用var FOO=FOO | |{};
,这意味着“FOO将被分配给FOO(如果它已经存在)或一个新的空白对象(如果FOO还不存在)
解决方案:
// 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!');
};
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.js
和Homer.js
,而无需覆盖彼此的方法(如果它们有不同的名称)。因此,您将始终得到一个FOO
对象,该对象具有方法skateboard
和donut
(耶!)
#2定义新对象
如果您已经阅读了第一个示例,那么您现在已经知道了|{}
的目的
因为如果没有现有的FOO
对象,则OR案例将变为活动状态并创建一个新对象,因此您可以为其分配函数。比如:
var FOO = {};
FOO.skateboard = function() {
alert('I like skateboarding!');
};
实际上,在上一个示例中,作用域是可以的,因为JS没有块scope@Alnitak-嗯,你说得对;我最近太多地使用闭包了,我忘记了最基本的东西。我将编辑答案。这正是事实,有两个js文件在开始时具有完全相同的声明,非常感谢+1阅读字里行间的内容并解释这样做的原因。当有人给出用户真正想要的答案而不仅仅是他要求的答案时,这总是好的。:)我想说的是#ifndef/#define for javascript:)|
在您想提供可选参数并在未提供时将其初始化为默认值时也非常有用:函数foo(arg1,optarg1,optarg2){optarg1=optarg1 | | |“默认值1”;optarg2=optart2 | |“defalt值2”}
@crazy2be如果默认值为truthy,那么这可能不起作用,但是虚假值也是合法的,因为|
操作符无法从falsey
中分辨未定义的。我不确定truthy和falsey是否应该作为实际单词永久存在。有趣,但不是exac