JavaScript条件不会像我期望的那样短路

时间:2014-11-13 22:04:04

标签: javascript conditional-statements short-circuiting

我是一名经验丰富的开发人员,但我遇到了一个问题需要一段时间来弄清楚并正在寻找解释。我依靠短路,花了比我更多的时间承认调试这个。如果这属于另一个Stack Exchange网站,请提供建议。

我希望以下内容评估为false,但它会通过:

(false && true || true) => true

好像它被解释为:

((false && true) || true) => true

......但解决方法是:

(false && (true || true)) => false

为什么false没有在第一个例子中短路操作?有什么样的前瞻我不知道吗?


解决方案摘要:对于那些(像我一样)从不知道条件运算符具有与数学运算符类似的优先级的人 - 暗示括号的相同概念适用:

3 * 2 + 1 => (3 * 2) + 1 => 7
false && true || true => (false && true) || true => true

1 个答案:

答案 0 :(得分:5)

逻辑AND(&&)的优先级高于逻辑OR(||)。

您可以通过添加示例中使用的括号来解决问题。

x && (y || z);

但是,使用显式if语句会更具可读性:

if (x && y) {
    z;
}

Here's a reference chart for operator precedence in JS。 (见#13和#14。)

如果您很难理解优先级,请尝试将*替换为&&,将+替换为||

x * y + z;

显然,按操作顺序,x * y将首先执行。因此,如果您想先执行y + z,请使用括号。

短路与语法无关。它只是一个布尔运算符的怪癖。所以不要把它想象成

  

我一直认为第一次失败的情况会使操作短路并进一步评估停止。

短路并没有打电话给某些" abort"退出整个操作的功能。如果它已经可以确定最终结果是什么,那么布尔运算符将忽略它们的第二个参数(b中的a && b)。 (例如,false && (anything)始终为false,因此&&是懒惰的,并且不会对第二个参数进行评估。)

  

我仍然不知道false && (anything)总是假的,但false && (anything) || somethingelse可能是真的。

好的,所以应用优先规则,我们得到:

(false && anything) || somethingelse

因此,首先评估&&。由于它很懒惰,它会看到false并立即返回false

(false) || somethingelse // `anything' is not evaluated

现在它已经||来评估了。它会看到false刚刚返回的&&,并且它不能短路,因为false || true仍然可以为真。因此,必须评估somethingelse以获得最终结果。

因此,代码if((false && anything) || somethingelse)基本上等同于if (somethingelse)