“var FOO = FOO || {}”(为该变量分配一个变量或一个空对象)在 Javascript 中是什么意思?

IT技术 javascript namespaces variable-declaration or-operator
2021-01-23 13:19:59

查看在线源代码,我在几个源文件的顶部发现了这个。

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

但我不知道有什么|| {}作用。

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

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

6个回答

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

这种在文件顶部看到的特殊模式用于创建命名空间,即一个命名对象,在该命名对象下可以创建函数和变量而不会过度污染全局对象。

究其原因,为什么它的使用是如此,如果你有两个(或更多)的文件:

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

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

这两个份额的同一个命名空间那么也没关系,其中责令这两个文件被加载,你仍然可以func1func2正确的中定义MY_NAMESPACE正确的对象。

加载的第一个文件将创建初始MY_NAMESPACE对象,任何随后加载的文件将扩充该对象。

有用的是,这还允许异步加载共享相同命名空间的脚本,从而缩短页面加载时间。如果<script>标签defer设置属性,您将无法知道它们将被解释的顺序,因此如上所述,这也解决了该问题。

确实是这样,有几个js文件开头的声明完全一样,非常感谢!
2021-03-14 13:19:59
@crazy2be 如果默认值为真则不起作用,但假值也是合法的,因为||操作员无法undefinedfalsey.
2021-03-16 13:19:59
+1 用于在字里行间阅读并解释这样做的原因。当有人给出用户真正想要的答案而不只是他要求的答案时,总是好的:)
2021-03-19 13:19:59
我想说这是 javascript 的 #ifndef/#define :)
2021-03-19 13:19:59
|| 当您想提供可选参数并将它们初始化为默认值(如果未提供)时,它也非常有用: function foo(arg1, optarg1, optarg2) { optarg1 = optarg1 || 'default value 1'; optarg2 = optart2 || 'defalt value 2';}
2021-04-06 13:19:59
var AEROTWIST = AEROTWIST || {};

基本上这一行是说将AEROTWIST变量设置为变量的值AEROTWIST,或将其设置为空对象。

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

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

这与说这个基本相同:

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

希望有帮助。

@Alnitak - 嗯,你说得对;我最近一直在处理闭包,我已经忘记了基础知识。我会编辑答案。
2021-03-15 13:19:59
实际上,在您的最后一个示例中,范围会很好,因为JS 没有块范围
2021-03-30 13:19:59

有两个主要部分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!');
};

在这种情况下,skateboard如果您在 HTML 中加载 JavaScript 文件homer.js之后bart.js函数将消失,因为 Homer 定义了一个新FOO对象(从而覆盖了 Bart 的现有对象),因此它只知道该donut函数。

所以你需要使用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而不覆盖彼此的方法(如果它们具有不同的名称)。所以你总是会得到一个FOO具有方法skateboarddonut(耶!)的对象。

#2 定义一个新对象

如果您已经阅读了第一个示例,那么您现在已经知道|| {}.

因为如果没有现有FOO对象,那么 OR-case 将变为活动状态并创建一个新对象,因此您可以为其分配功能。喜欢:

var FOO = {};

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

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

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在前面aa进入函数的执行上下文作为一个正式的参数,因此它已经被宣布。
2021-03-10 13:19:59

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