[英]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 && b
中a && 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 butfalse && (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.