Looking at an online source code I came across this at the top of several source files.
看一下在线源代码,我在几个源文件的顶部看到了这个。
var FOO = FOO || {};
FOO.Bar = …;
But I have no idea what || {}
does.
但我不知道什么是|| {}。
I know {}
is equal to new Object()
and I think the ||
is for something like "if it already exists use its value else use the new object.
我知道{}等于新的Object(),我认为是||是为了“如果它已经存在使用它的值,否则使用新对象。
Why would I see this at the top of a source file?
为什么我会在源文件的顶部看到这个?
7 个解决方案
#1
141
Your guess as to the intent of || {}
is pretty close.
你猜测||的意图{}非常接近。
This particular pattern when seen at the top of files is used to create a namespace, i.e. a named object under which functions and variables can be created without unduly polluting the global object.
当在文件顶部看到时,这种特定模式用于创建命名空间,即命名对象,在该命名对象下可以创建函数和变量而不会过度污染全局对象。
The reason why it's used is so that if you have two (or more) files:
使用它的原因是,如果你有两个(或更多)文件:
var MY_NAMESPACE = MY_NAMESPACE || {};
MY_NAMESPACE.func1 = {
}
and
和
var MY_NAMESPACE = MY_NAMESPACE || {};
MY_NAMESPACE.func2 = {
}
both of which share the same namespace it then doesn't matter in which order the two files are loaded, you still get func1
and func2
correctly defined within the MY_NAMESPACE
object correctly.
两个文件共享相同的命名空间然后加载两个文件的顺序无关紧要,你仍然可以正确地在MY_NAMESPACE对象中正确定义func1和func2。
The first file loaded will create the initial MY_NAMESPACE
object, and any subsequently loaded file will augment the object.
加载的第一个文件将创建初始MY_NAMESPACE对象,任何后续加载的文件将扩充该对象。
Usefully, this also allows asynchronous loading of scripts that share the same namespace which can improve page loading times. If the <script>
tags have the defer
attribute set you can't know in which order they'll be interpreted, so as described above this fixes that problem too.
有用的是,这也允许异步加载共享相同命名空间的脚本,这可以改善页面加载时间。如果
#2
20
var AEROTWIST = AEROTWIST || {};
Basically this line is saying set the AEROTWIST
variable to the value of the AEROTWIST
variable, or set it to an empty object.
基本上这一行是说将AEROTWIST变量设置为AEROTWIST变量的值,或者将其设置为空对象。
The double pipe ||
is an OR statement, and the second part of the OR is only executed if the first part returns false.
双管||是OR语句,OR的第二部分仅在第一部分返回false时执行。
Therefore, if AEROTWIST
already has a value, it will be kept as that value, but if it hasn't been set before, then it will be set as an empty object.
因此,如果AEROTWIST已经有一个值,它将保留为该值,但如果之前未设置,则将其设置为空对象。
it's basically the same as saying this:
它与说这个基本相同:
if(!AEROTWIST) {var AEROTWIST={};}
Hope that helps.
希望有所帮助。
#3
5
Another common use for || is to set a default value for an undefined function parameter also:
||的另一个常见用途是也为未定义的函数参数设置默认值:
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
The equivalent in other programming usually is:
其他编程中的等价物通常是:
function display(a = 'default') {
// ...
}
#4
4
There are two main parts that var FOO = FOO || {};
covers.
var FOO = FOO ||有两个主要部分{};盖子。
#1 Preventing overrides
#1防止覆盖
Imagine you have your code split over multiple files and your co-workers are also working on an Object called FOO
. Then it could lead to the case that someone already defined FOO
and assigned functionality to it (like a skateboard
function). Then you would override it, if you were not checking if it already exists.
想象一下,您的代码分为多个文件,您的同事也在处理一个名为FOO的对象。然后它可能导致某人已经定义了FOO并为其分配了功能(如滑板功能)。如果你没有检查它是否已经存在,那么你会覆盖它。
Problematic case:
有问题的案例:
// 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!');
};
In this case the skateboard
function will be gone if you load the JavaScript file homer.js
after bart.js
in your HTML because Homer defines a new FOO
object (and thus overrides the existing one from Bart) so it only knows about the donut
function.
在这种情况下,如果您在HTML中的bart.js之后加载JavaScript文件homer.js,滑板功能将会消失,因为Homer定义了一个新的FOO对象(从而覆盖Bart中的现有对象),因此它只知道甜甜圈功能。
So you need to use var FOO = FOO || {};
which means "FOO will be assigned to FOO (if it exists already) or a new blank object (if FOO does not exist already).
所以你需要使用var FOO = FOO || {};这意味着“FOO将被分配给FOO(如果它已存在)或新的空白对象(如果FOO已经不存在)。
Solution:
解:
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!');
};
Because Bart and Homer are now checking for the existence of FOO
before they define their methods, you can load bart.js
and homer.js
in any order without overriding each other's methods (if they have different names). So you will always get a FOO
object which has the methods skateboard
and donut
(Yay!).
因为Bart和Homer现在在定义他们的方法之前检查FOO的存在,你可以按任何顺序加载bart.js和homer.js而不覆盖彼此的方法(如果他们有不同的名字)。所以你总会得到一个FOO对象,它有滑板和甜甜圈的方法(耶!)。
#2 Defining a new object
#2定义一个新对象
If you've read through the first example then you already now what's the purpose of the || {}
.
如果您已经阅读了第一个示例,那么您现在已经知道了||的目的是什么{}。
Because if there is no existing FOO
object then the OR-case will become active and creates a new object, so you can assign functions to it. Like:
因为如果没有现有的FOO对象,则OR-case将变为活动状态并创建一个新对象,因此您可以为其分配函数。喜欢:
var FOO = {};
FOO.skateboard = function() {
alert('I like skateboarding!');
};
#5
3
If there is no value in AEROTWIST or it is null or undefined the value assigned to the new AEROTWIST will be {} (a blank object)
如果AEROTWIST中没有值或者它为null或未定义,则分配给新AEROTWIST的值将为{}(空白对象)
#6
1
The ||
operator takes two values:
||运算符有两个值:
a || b
If a is truthy, it will return a
. Otherwise, it will return b
.
如果a是真实的,它将返回a。否则,它将返回b。
The falsy values are null
, undefined
, 0
, ""
, NaN
and false
. The truthy values are everything else.
虚假值为null,undefined,0,“”,NaN和false。真实的价值观是其他一切。
So if a
has not been set (is it undefined
) it will return b
.
因此,如果a尚未设置(未定义),则返回b。
#7
-1
Notice that in some version of IE this code won't work as expected. Because the var
, the variable is redefined and assigned so – if I recall correctly the issue – you'll end up to have always a new object. That should fix the issue:
请注意,在某些版本的IE中,此代码将无法按预期工作。因为var,变量被重新定义并分配 - 如果我没记错的话 - 你最终会得到一个新的对象。这应该解决问题:
var AEROTWIST;
AEROTWIST = AEROTWIST || {};
#1
141
Your guess as to the intent of || {}
is pretty close.
你猜测||的意图{}非常接近。
This particular pattern when seen at the top of files is used to create a namespace, i.e. a named object under which functions and variables can be created without unduly polluting the global object.
当在文件顶部看到时,这种特定模式用于创建命名空间,即命名对象,在该命名对象下可以创建函数和变量而不会过度污染全局对象。
The reason why it's used is so that if you have two (or more) files:
使用它的原因是,如果你有两个(或更多)文件:
var MY_NAMESPACE = MY_NAMESPACE || {};
MY_NAMESPACE.func1 = {
}
and
和
var MY_NAMESPACE = MY_NAMESPACE || {};
MY_NAMESPACE.func2 = {
}
both of which share the same namespace it then doesn't matter in which order the two files are loaded, you still get func1
and func2
correctly defined within the MY_NAMESPACE
object correctly.
两个文件共享相同的命名空间然后加载两个文件的顺序无关紧要,你仍然可以正确地在MY_NAMESPACE对象中正确定义func1和func2。
The first file loaded will create the initial MY_NAMESPACE
object, and any subsequently loaded file will augment the object.
加载的第一个文件将创建初始MY_NAMESPACE对象,任何后续加载的文件将扩充该对象。
Usefully, this also allows asynchronous loading of scripts that share the same namespace which can improve page loading times. If the <script>
tags have the defer
attribute set you can't know in which order they'll be interpreted, so as described above this fixes that problem too.
有用的是,这也允许异步加载共享相同命名空间的脚本,这可以改善页面加载时间。如果
#2
20
var AEROTWIST = AEROTWIST || {};
Basically this line is saying set the AEROTWIST
variable to the value of the AEROTWIST
variable, or set it to an empty object.
基本上这一行是说将AEROTWIST变量设置为AEROTWIST变量的值,或者将其设置为空对象。
The double pipe ||
is an OR statement, and the second part of the OR is only executed if the first part returns false.
双管||是OR语句,OR的第二部分仅在第一部分返回false时执行。
Therefore, if AEROTWIST
already has a value, it will be kept as that value, but if it hasn't been set before, then it will be set as an empty object.
因此,如果AEROTWIST已经有一个值,它将保留为该值,但如果之前未设置,则将其设置为空对象。
it's basically the same as saying this:
它与说这个基本相同:
if(!AEROTWIST) {var AEROTWIST={};}
Hope that helps.
希望有所帮助。
#3
5
Another common use for || is to set a default value for an undefined function parameter also:
||的另一个常见用途是也为未定义的函数参数设置默认值:
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
The equivalent in other programming usually is:
其他编程中的等价物通常是:
function display(a = 'default') {
// ...
}
#4
4
There are two main parts that var FOO = FOO || {};
covers.
var FOO = FOO ||有两个主要部分{};盖子。
#1 Preventing overrides
#1防止覆盖
Imagine you have your code split over multiple files and your co-workers are also working on an Object called FOO
. Then it could lead to the case that someone already defined FOO
and assigned functionality to it (like a skateboard
function). Then you would override it, if you were not checking if it already exists.
想象一下,您的代码分为多个文件,您的同事也在处理一个名为FOO的对象。然后它可能导致某人已经定义了FOO并为其分配了功能(如滑板功能)。如果你没有检查它是否已经存在,那么你会覆盖它。
Problematic case:
有问题的案例:
// 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!');
};
In this case the skateboard
function will be gone if you load the JavaScript file homer.js
after bart.js
in your HTML because Homer defines a new FOO
object (and thus overrides the existing one from Bart) so it only knows about the donut
function.
在这种情况下,如果您在HTML中的bart.js之后加载JavaScript文件homer.js,滑板功能将会消失,因为Homer定义了一个新的FOO对象(从而覆盖Bart中的现有对象),因此它只知道甜甜圈功能。
So you need to use var FOO = FOO || {};
which means "FOO will be assigned to FOO (if it exists already) or a new blank object (if FOO does not exist already).
所以你需要使用var FOO = FOO || {};这意味着“FOO将被分配给FOO(如果它已存在)或新的空白对象(如果FOO已经不存在)。
Solution:
解:
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!');
};
Because Bart and Homer are now checking for the existence of FOO
before they define their methods, you can load bart.js
and homer.js
in any order without overriding each other's methods (if they have different names). So you will always get a FOO
object which has the methods skateboard
and donut
(Yay!).
因为Bart和Homer现在在定义他们的方法之前检查FOO的存在,你可以按任何顺序加载bart.js和homer.js而不覆盖彼此的方法(如果他们有不同的名字)。所以你总会得到一个FOO对象,它有滑板和甜甜圈的方法(耶!)。
#2 Defining a new object
#2定义一个新对象
If you've read through the first example then you already now what's the purpose of the || {}
.
如果您已经阅读了第一个示例,那么您现在已经知道了||的目的是什么{}。
Because if there is no existing FOO
object then the OR-case will become active and creates a new object, so you can assign functions to it. Like:
因为如果没有现有的FOO对象,则OR-case将变为活动状态并创建一个新对象,因此您可以为其分配函数。喜欢:
var FOO = {};
FOO.skateboard = function() {
alert('I like skateboarding!');
};
#5
3
If there is no value in AEROTWIST or it is null or undefined the value assigned to the new AEROTWIST will be {} (a blank object)
如果AEROTWIST中没有值或者它为null或未定义,则分配给新AEROTWIST的值将为{}(空白对象)
#6
1
The ||
operator takes two values:
||运算符有两个值:
a || b
If a is truthy, it will return a
. Otherwise, it will return b
.
如果a是真实的,它将返回a。否则,它将返回b。
The falsy values are null
, undefined
, 0
, ""
, NaN
and false
. The truthy values are everything else.
虚假值为null,undefined,0,“”,NaN和false。真实的价值观是其他一切。
So if a
has not been set (is it undefined
) it will return b
.
因此,如果a尚未设置(未定义),则返回b。
#7
-1
Notice that in some version of IE this code won't work as expected. Because the var
, the variable is redefined and assigned so – if I recall correctly the issue – you'll end up to have always a new object. That should fix the issue:
请注意,在某些版本的IE中,此代码将无法按预期工作。因为var,变量被重新定义并分配 - 如果我没记错的话 - 你最终会得到一个新的对象。这应该解决问题:
var AEROTWIST;
AEROTWIST = AEROTWIST || {};