提问人:Ricardo Sanchez 提问时间:6/22/2011 最后编辑:JJJRicardo Sanchez 更新时间:10/26/2021 访问量:22305
“var FOO = FOO ||{}“(为该变量分配一个变量或一个空对象)在 Javascript 中是什么意思?
What does "var FOO = FOO || {}" (assign a variable or an empty object to that variable) mean in Javascript?
问:
查看在线源代码,我在几个源文件的顶部遇到了它。
var FOO = FOO || {};
FOO.Bar = …;
但我不知道有什么作用。|| {}
我知道等于,我认为是用于“如果它已经存在,请使用其值,否则使用新对象。{}
new Object()
||
为什么我会在源文件的顶部看到它?
答:
如果 AEROTWIST 中没有值,或者该值为 null 或未定义,则分配给新 AEROTWIST 的值将为 {}(空白对象)
运算符采用两个值:||
a || b
如果 a 为真,它将返回 。否则,它将返回 .a
b
假值为 、 、 、 和 。真实的价值观是其他一切。null
undefined
0
""
NaN
false
因此,如果尚未设置(是)它将返回。a
undefined
b
评论
||
var AEROTWIST = AEROTWIST || {};
基本上,这一行是说将变量设置为变量的值,或将其设置为空对象。AEROTWIST
AEROTWIST
双管是 OR 语句,仅当第一部分返回 false 时,才会执行 OR 的第二部分。||
因此,如果已经有一个值,它将保留为该值,但如果之前没有设置,则它将被设置为空对象。AEROTWIST
这基本上和说的一样:
if(!AEROTWIST) {var AEROTWIST={};}
希望能有所帮助。
评论
你对意图的猜测非常接近。|| {}
当在文件顶部看到时,这种特殊的模式用于创建命名空间,即一个命名对象,在该对象下可以创建函数和变量,而不会过度污染全局对象。
之所以使用它,是因为如果您有两个(或更多)文件:
var MY_NAMESPACE = MY_NAMESPACE || {};
MY_NAMESPACE.func1 = {
}
和
var MY_NAMESPACE = MY_NAMESPACE || {};
MY_NAMESPACE.func2 = {
}
两者共享相同的命名空间,然后无论两个文件的加载顺序如何,您仍然可以在对象中正确获取并正确定义。func1
func2
MY_NAMESPACE
加载的第一个文件将创建初始对象,任何后续加载的文件都将扩充该对象。MY_NAMESPACE
有用的是,这还允许异步加载共享相同命名空间的脚本,这可以缩短页面加载时间。如果标签设置了属性,则无法知道它们将按何种顺序进行解释,因此如上所述,这也解决了该问题。<script>
defer
评论
||
当您想要提供可选参数并将它们初始化为默认值(如果未提供)时,也非常有用:function foo(arg1, optarg1, optarg2) { optarg1 = optarg1 || 'default value 1'; optarg2 = optart2 || 'defalt value 2';}
||
undefined
falsey
||是为未定义的函数参数设置默认值:
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
a
a
请注意,在某些版本的 IE 中,此代码无法按预期工作。因为 ,变量被重新定义和分配,所以 - 如果我没记错的话 - 你最终会有一个新对象。这应该可以解决问题:var
var AEROTWIST;
AEROTWIST = AEROTWIST || {};
主要包括两个部分。var FOO = FOO || {};
#1 防止覆盖
想象一下,您的代码被拆分为多个文件,而您的同事也在处理一个名为 的对象。然后,它可能导致有人已经定义并为其分配了功能(例如函数)的情况。然后,如果您不检查它是否已经存在,您将覆盖它。FOO
FOO
skateboard
问题案例:
// 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 中加载 JavaScript 文件,该函数将消失,因为 Homer 定义了一个新对象(因此覆盖了 Bart 的现有对象),因此它只知道该函数。skateboard
homer.js
bart.js
FOO
donut
因此,您需要使用 which 表示“FOO 将被分配给 FOO(如果它已经存在)或一个新的空白对象(如果 FOO 不存在)。var 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 现在在定义其方法之前检查是否存在 of,因此您可以按任何顺序加载,而无需覆盖彼此的方法(如果它们具有不同的名称)。所以你总是会得到一个对象,它有方法和(耶!FOO
bart.js
homer.js
FOO
skateboard
donut
#2 定义一个新对象
如果您已经通读了第一个示例,那么您现在已经知道 .|| {}
因为如果没有现有的对象,那么 OR-case 将变为活动状态并创建一个新对象,因此您可以为其分配函数。喜欢:FOO
var FOO = {};
FOO.skateboard = function() {
alert('I like skateboarding!');
};
对于 || 操作,JS 将返回它找到的第一个“真实”值(从左到右读取):
var bob = false || undefined || 0 || null || "hi"
// ^ ^ ^ ^ ^
// nope nope nope nope yip
//
// => bob = "hi"
// --------------
// breaking
// --------------
var bob = false || "hi" || 0 || null || undefined
// ^ ^
// nope yip <-- stops here
// the rest are ignored
//
// => bob = "hi"
另一个技巧是在访问之前使用 && (and) 来确保某些东西存在。
对于&&操作,JS将返回它找到的LAST“truthy”值(从左到右读取)。
例如,如果尝试从多级对象中读取属性。
var obj = {
foo : {
bar : "hi"
}
}
var bob = obj && obj.foo && obj.foo.bar;
// ^ ^ ^
// yip yip use this
//
// => bob = "hi"
// --------------
// breaking:
// --------------
var bob = obj && obj.foo && obj.foo.sally && obj.foo.bar;
// ^ ^ ^
// yip yip nope <-- stops here,
// ^ and returns the last "yip"
// | the rest are ignored |
// '-----------------------------------------------'
//
// => bob = obj.foo
两者 ||&& 操作从左到右读取...因此,您可以拥有通常可能会向右侧抛出错误的东西,因为一旦 JS 检测到真值/假值,它就会停止从左到右读取。
评论