简体   繁体   English

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

[英]JavaScript conditional not short circuiting like I would expect

I am an experienced developer, but I just ran into an issue that took me a while to figure out and am looking for an explanation. 我是一个经验丰富的开发人员,但是我遇到了一个问题,我花了一些时间才想出办法,并寻求解释。 I was relying on short circuiting and spent more time than I care to admit debugging this. 我一直依靠短路,花了比我更愿意接受调试的时间。 If this belongs on another Stack Exchange site, please advise. 如果它属于另一个Stack Exchange网站,请告知。

I expect the following to evaluate to false, but it passes: 我希望以下内容评估为false,但可以通过:

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

It is as though it's being interpreted as this: 好像它被解释为:

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

... but the solution is this: ...但是解决方案是这样的:

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

Why doesn't false short circuit the operation in the first example? 为什么在第一个示例中不false短路操作? Is there some sort of lookahead I don't know about? 我有不知道的前瞻性吗?


Solution summary: For those who (like me) never knew conditional operators have a similar precedence as mathematical operators - the same concept of implied parenthesis applies: 解决方案摘要:对于那些像我这样从来不知道条件运算符具有与数学运算符相似的优先级的人- 隐含括号的概念相同:

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

Logical AND ( && ) has a higher precedence than logical OR ( || ). 逻辑AND( && )的优先级高于逻辑OR( || )。

You could fix the problem by adding the parentheses you used in your example. 您可以通过添加示例中使用的括号来解决此问题。

x && (y || z);

However, it would be much more readable to use an explicit if statement instead: 但是,使用显式的if语句代替可读性更高:

if (x && y) {
    z;
}

Here's a reference chart for operator precedence in JS . 这是JS中运算符优先级的参考图 (See #13 and #14.) (请参阅#13和#14。)

If you're having a hard time understanding precedence, try substituting * for && and + for || 如果您很难理解优先级,请尝试用*替换&&+替换|| :

x * y + z;

Clearly, by order of operations, the x * y will be executed first. 显然,按照操作顺序,将首先执行x * y So if you want to execute the y + z first instead, you would use parentheses. 因此,如果您想先执行y + z ,则可以使用括号。

Short circuiting has nothing to do with the syntax. 短路与语法无关。 It's simply a quirk of boolean operators. 这只是布尔运算符的一个怪癖。 So don't think of it like 所以不要想像

I always thought that the first failed condition short circuits the operation and further evaluation stops. 我一直认为,第一个失败的条件会使操作短路,进而停止评估。

The short circuiting doesn't call some sort of "abort" function that exits the entire operation. 短路不会调用某种“中止”功能来退出整个操作。 It's simply that the boolean operators will ignore their second argument ( b in a && b ) if it's already ascertainable what the final result will be. 如果布尔运算符已经可以确定最终结果是什么,则布尔运算符将忽略它们的第二个参数( b a && ba && b )。 (For example, false && (anything) is always false, so && is lazy and doesn't bother evaluating the second argument.) (例如, false && (anything)始终为false,因此&&懒惰,不会费心计算第二个参数。)

I still don't get how false && (anything) is always false but false && (anything) || somethingelse 我仍然不知道false && (anything)总是假,而是false && (anything) || somethingelse是怎么回事? false && (anything) || somethingelse can be true. false && (anything) || somethingelse可能是对的。

Okay, so applying the precedence rules, we get: 好的,因此应用优先规则,我们得到:

(false && anything) || somethingelse

Therefore, the && is evaluated first. 因此, &&首先被评估。 Since it's lazy, it sees the false and immediately returns false : 由于它很懒,它会看到false并立即返回false

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

Now it's || 现在是|| 's turn to evaluate. 轮到评估了。 It sees the false that && just returned, and it can't short-circuit because false || true 它看到&&刚刚返回的false ,并且由于false || true而无法短路。 false || true could still be true. false || true可能仍然是true。 So it has to evaluate the somethingelse to get the final result. 因此,它必须评估somethingelse才能获得最终结果。

Therefore, the code if((false && anything) || somethingelse) is essentially equivalent to if (somethingelse) . 因此,代码if((false && anything) || somethingelse)本质上等同于if (somethingelse)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM