17

请有人向我解释这行代码的作用:

var list  = calls[ev] || (calls[ev] = {});

我最好的猜测:

它使用calls.xxx的值设置变量“list”,其中xxx是一个变量,ev。如果 call[ev] 不存在,那么它会将其创建为一个空对象并将该空对象分配给“list”。是对的吗?

为什么要使用括号?在哪里可以找到有关使用 || 的更多信息 设置变量时,以及在这种情况下使用括号?谢谢!

4

4 回答 4

16

这段代码相当于

var list;
if (calls[ev])
  list = calls[ev];
else {
  calls[ev] = {};
  list = calls[ev];
}

使用了该语言的两个特性:

  1. 布尔表达式的快捷计算(考虑a || b. If ais truethenb不计算)。因此,如果您分配var v = a || b;a评估可以转换为的东西true,则b不会评估。
  2. 赋值语句计算为最后一个赋值(启用var a = b = c;

为了避免这种解释,括号是必要的:

var list = (calls[ev] || calls[ev]) = {};

(这是一个错误)。

于 2012-03-06T15:14:41.987 回答
11

你的猜测是对的。这是在 JavaScript 中为变量声明“默认”值的常用方法。

function foo(bar) {
    var bar = bar || 0; //This sets bar to 0 if it's not already set
    console.log(bar);
}

它的工作方式是,在 JavaScript 中,未定义的变量是虚假的,这意味着在任何布尔比较操作中,它将评估为false. 然后,您可以使用 OR 运算符组合两个值,它将返回计算结果为 的第一个值true

于 2012-03-06T15:11:51.210 回答
4

||or 'logical OR' 具有比赋值运算符更高的优先级=,因此括号对于确保此成语以正确的顺序进行评估是必要的

另一件需要注意的事情是,包括 Javascript 在内的许多语言都提供了对 AND 和 OR 等布尔运算符的短路评估。如果逻辑或的第一个操作数评估为真,则无需评估第二个操作数,因为它不会对结果产生影响。

理解这一点,你会发现这不是某种特殊的赋值语法,而是一种习语或模式,它利用语言特性来提供更紧凑的想法表示。

于 2012-03-06T15:11:13.387 回答
1

你的第一个猜测是正确的。这是初始化 javascript 命名空间的常见模式。它用于确保您不会覆盖以前的同名对象。大多数流行的库都会做类似的事情来创建它们的命名空间对象。

括号在那里,以便以正确的顺序评估表达式。

于 2012-03-06T15:16:32.433 回答