JavaScript 条件不像我期望的那样短路
Posted
技术标签:
【中文标题】JavaScript 条件不像我期望的那样短路【英文标题】:JavaScript conditional not short circuiting like I would expect 【发布时间】:2015-01-11 05:06:57 【问题描述】:我是一位经验丰富的开发人员,但我刚刚遇到了一个问题,我花了一段时间才弄清楚并正在寻找解释。我依赖于短路并且花费了比我愿意承认的调试更多的时间。如果这属于另一个 Stack Exchange 网站,请告知。
我希望以下结果为假,但它通过了:
(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】:逻辑与 (&&
) 的优先级高于逻辑或 (||
)。
您可以通过添加您在示例中使用的括号来解决问题。
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
,则应使用括号。
短路与语法无关。这只是布尔运算符的一个怪癖。所以不要这么想
我一直认为第一个失败的条件会使操作短路,进一步的评估会停止。
短路不会调用某种退出整个操作的“中止”函数。如果已经可以确定最终结果是什么,那么布尔运算符将忽略它们的第二个参数(a && b
中的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)
。
【讨论】:
感谢您的快速回复。我的真实代码使用 if 语句和业务逻辑。我只是想简化它以在此处发布if(false && true || true) /* do stuff */
。我想我不明白优先级如何影响结果。我一直认为第一个失败的条件会使操作短路并且进一步的评估停止。
...感谢您的进一步解释。这是一个新概念——不知道它是如何让我避开了 10 年的。我可以在几分钟内接受。
我仍然不明白 false && (anything)
总是假的 但false && (anything) || somethingelse
可能是真的。无需进一步解释……去做研究。
@RyanWheale 哦,这是个好问题。等一下,无论如何,为了未来的读者,我将在我的答案中编辑另一段。以上是关于JavaScript 条件不像我期望的那样短路的主要内容,如果未能解决你的问题,请参考以下文章