我正在尝试选择一个可靠的运算符,“如果未定义或初始化变量,则声明并初始化”。
考虑一个例子(语义并不重要):
window.test ?= 123
location.origin ||= location.protocol + "//" + location.host
这会被翻译成以下Javascript:
var _ref;
if ((_ref = window.test) == null) {
window.test = 123;
}
location.origin || (location.origin = location.protocol + "//" + location.host);
哪种方式更好?在我看来,||=
运算符更可靠,因为它也说明了“未定义”但是为什么CoffeeScript会推广使用?=
呢?我错过了什么吗?
答案 0 :(得分:7)
在JavaScript中,undefined == null
1 ,因此它确实考虑了undefined
。 ||=
通常是不受欢迎的,因为它会覆盖任何虚假值,即使它不是null
或undefined
,例如,零或假。
1 在JavaScript中,==
有时会隐式强制执行值,其中一个案例是null
和undefined
。 (见section 11.9.3 in the specification的第2和第3项)。
答案 1 :(得分:0)
我正在尝试选择一个可靠的运算符,“如果未定义或初始化变量,则声明并初始化”。
无法在符合ECMA-262的主机中有条件地声明变量。可以测试全局变量的存在,因为它们是全局(窗口)对象的属性(但它不会告诉您它们是否被创建为全局变量或属性)。测试全局:
// In global scope:
var global = this;
// Wherever:
if (global.hasOwnProperty('foo')) { // throws an error in IE
// foo is a property of the global object
}
无法测试局部变量(例如在函数内),因为您无法访问变量对象或执行上下文对象来测试它,您所能做的就是针对undefined
进行测试或使用{ {1}}(丑陋的)。但需要这样做是非常糟糕的设计。
如果打算有条件地创建全局对象的属性,那么上面的内容将导致:
try..catch
但是,如果您还想测试属性是否已分配值,则:
if (!global.hasOwnProperty('foo')) { // throws an error in IE
global.foo = 'whatever';
}
似乎更合适,好像上面的内容返回true,然后它既没有声明,也没有赋值,或者被赋值为if (typeof global.foo == 'undefined') { // works everywhere
。在所有情况下,您可能希望现在分配一个值。
对undefined
进行测试似乎不合理,因为它具有该值的唯一方法是显式分配(这意味着该属性存在且已被赋值)。