JavaScript没有像我预期的那样短路
我是一个经验丰富的开发人员,但我刚刚遇到了一个问题,我花了一段时间才弄明白,我正在寻找一个解释。我依赖于短路,花了比我愿意承认的更多的时间调试这个。如果这属于其他StackExchange站点,请告知 我希望下面的计算结果为false,但它通过了:JavaScript没有像我预期的那样短路,javascript,conditional-statements,short-circuiting,Javascript,Conditional Statements,Short Circuiting,我是一个经验丰富的开发人员,但我刚刚遇到了一个问题,我花了一段时间才弄明白,我正在寻找一个解释。我依赖于短路,花了比我愿意承认的更多的时间调试这个。如果这属于其他StackExchange站点,请告知 我希望下面的计算结果为false,但它通过了: (false && true || true) => true 就好像它被解释为: ((false && true) || true) => true 。。。但解决办法是: (false &&a
(false && true || true) => true
就好像它被解释为:
((false && true) || true) => true
。。。但解决办法是:
(false && (true || true)) => false
为什么在第一个示例中,false
不会使操作短路?有什么我不知道的前瞻吗
解决方案摘要:对于那些(像我一样)从来不知道条件运算符与数学运算符具有相似优先级的人,同样的隐含括号概念也适用: 逻辑AND(
&&
)的优先级高于逻辑OR(|
)
您可以通过添加示例中使用的括号来解决此问题
x && (y || z);
但是,使用显式的if
语句将更具可读性:
if (x && y) {
z;
}
。(见第13条和第14条。)
如果您很难理解优先级,请尝试用*
替换&&
,用+
替换|
:
x * y + z;
显然,按照操作顺序,将首先执行x*y
。因此,如果您想先执行y+z
,则可以使用括号
短路与语法无关。这只是布尔运算符的一个怪癖。所以不要把它想成那样
我一直认为第一个失败的条件会使操作短路,并停止进一步的评估
短路不会调用退出整个操作的某种“中止”函数。很简单,如果已经确定最终结果是什么,布尔运算符将忽略第二个参数(a&b
)。(例如,false&&(anything)
总是false,因此&&&
是懒惰的,不需要计算第二个参数。)
我仍然不明白false&&(任何东西)
怎么总是假的,但是false&&(任何东西)| |有些东西可能是真的
好的,应用优先规则,我们得到:
(false && anything) || somethingelse
因此,首先评估&&
。由于它是惰性的,因此它会看到false
,并立即返回false
:
(false) || somethingelse // `anything' is not evaluated
现在轮到|
进行评估了。它看到刚刚返回的&
的false
,它不能短路,因为false | | true
仍然可能是true。因此,它必须对somethingelse
进行评估,以获得最终结果
因此,代码if((false&&anything)| | somethingelse)
本质上等同于if(somethingelse)
感谢您的快速回复。我真正的代码使用if语句和业务逻辑。我只是想简化它,以便在这里发布if(false&&true | | true){/*do stuff*/}
。我想我不明白优先级是如何影响结果的。我一直认为第一个失败的条件会使操作短路,进一步的评估会停止。。。。谢谢你的进一步解释。这是一个新概念——不知道它是如何在10年内避免了我。我可以在几分钟内接受。我仍然不明白false&&(任何东西)
怎么总是假的,但是false&&(任何东西)|有些东西可以是真的。不需要进一步解释。。。去做研究。@RyanWheale哦,这是个好问题。等等,为了未来读者的利益,我将在我的答案中编辑另一段。
(false) || somethingelse // `anything' is not evaluated