0

我正在尝试为“如果未定义或初始化变量,则声明并初始化”选择一个可靠的运算符。

考虑一个例子(语义并不重要):

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 提倡使用?=代替呢?我错过了什么吗?

4

2 回答 2

7

在 JavaScript 中,undefined == null1,所以它确实解释了undefined. ||=通常是不可取的,因为它会覆盖任何假值,即使它不是nullor undefined,例如,零或假。

1在 JavaScript 中,==有时会隐式强制值,其中一种情况是nulland undefined。(参见规范中第 11.9.3 节的第 2 和第 3 项)。

于 2013-03-07T02:05:08.417 回答
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或使用try..catch(丑陋)。但需要这样做是非常糟糕的设计。

如果意图是有条件地创建全局对象的属性,那么上述导致:

if (!global.hasOwnProperty('foo')) { // throws an error in IE
  global.foo = 'whatever';
}

但是,如果您还想测试该属性是否已被赋值,那么:

if (typeof global.foo == 'undefined') { // works everywhere

似乎更合适,好像上面返回 true,然后它没有被声明,没有被赋值,或者被赋值为undefined. 在所有情况下,您现在可能都想分配一个值。

测试null似乎并不明智,因为它具有该值的唯一方法是显式分配它(这意味着该属性存在并且已被分配一个值)。

于 2013-03-07T02:46:05.537 回答