JavaScript 条件不像我期望的那样短路
JavaScript conditional not short circuiting like I would expect
我是一个经验丰富的开发人员,但我刚刚遇到了一个问题,花了我一段时间才弄清楚,正在寻找解释。我依靠短路,花了比我愿意承认调试的时间多。如果这属于另一个堆栈 交换站点,请告知。
我希望以下内容的评估结果为假,但它通过了:
(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
逻辑 AND ( &&
) 的优先级高于逻辑 OR (||
)。
您可以通过添加示例中使用的括号来解决此问题。
x && (y || z);
但是,改用显式 if
语句会更具可读性:
if (x && y) {
z;
}
下面是 JS 中运算符优先级的参考图表。(参见#13和#14。
如果您很难理解优先级,请尝试用*
代替&&
,用+
代替||
:
x * y + z;
显然,按照操作顺序,x * y
将首先执行。因此,如果要先执行y + z
,则应使用括号。
短路与语法无关。这只是布尔运算符的一个怪癖。所以不要把它想成
我一直认为第一个失败条件会使操作短路,进一步的评估会停止。
短路不会调用退出整个操作的某种"中止"函数。只是布尔运算符将忽略他们的第二个参数(b
a && b
),如果它已经可以确定最终结果是什么。(例如,false && (anything)
总是假的,所以&&
很懒惰,不会费心计算第二个参数。
我仍然不明白
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)
。
- 三元对短路
- 为什么jasmine期望不验证是否抛出了错误
- Backbone+RequireJS+Mediator模式导致视图逻辑短路和无限循环
- Facebook:当发布期望对象引用时显示打开的图形对话框
- React+Redux-期望reducer是一个函数
- “期望赋值或函数调用,而是看到了表达式.” - 不必要的控制台.log
- 地图(int,int)期望由帖子请求
- JavaScript短路评估错误
- Chai 期望 [函数] 抛出一个(错误)未通过测试(使用 Node)
- 在 JS 中短路空数组会产生意外结果:“[] ||真 == []'
- 这是链接chai.js's期望在守夜
- Js提示:“;期望一个赋值或函数调用,而看到一个表达式“;,Switch语句
- 获得正确的数据,但不是我期望的数据
- 显示Jasmine运行的测试/期望的总数
- IE10 Javascript”;期望函数”;
- 函数在我期望长度为 17 的地图时返回空
- 为什么这个字符串比较在Jest的期望中没有失败
- 柴 js 期望属性值为空数组
- 期望一个标识符,但找到了“else”
- JavaScript 条件不像我期望的那样短路