我是一名经验丰富的开发人员,但我遇到了一个问题需要一段时间来弄清楚并正在寻找解释。我依靠短路,花了比我更多的时间承认调试这个。如果这属于另一个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
答案 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)
。