[英]Why does short-circuit evaluation work when operator precedence says it shouldn't?
在JavaScript和Java中 ,equals运算符( ==
或===
)的优先级高于OR运算符( ||
)。 然而,两种语言( JS , Java )都支持if
语句中的短路:
当我们有if(true || anything())
,不评估anything()
。
您还可以使用以下表达式: true || foo == getValue())
true || foo == getValue())
- 例如在输出语句中,例如console.log(...);
,或在作业中。
现在,根据运算符优先级,不应该发生短路,如===
= ==
> ||
在优先权方面。 (换句话说,首先应该进行比较,因为相等检查具有比OR比较更高的优先级,因此应该调用getValue()
。但它确实如此。 不调用getValue()
(可以通过将输出语句放入其正文中来轻松检查)。
为什么(当运算符优先说它不应该时,短路工作)?
还是我困惑的事情?
还是我困惑的事情?
你是。 我认为将优先权视为分组而非排序要简单得多。 它会影响评价的顺序,但仅仅是因为它改变了分组。
我不确定Javascript,但在Java操作数总是按从左到右的顺序进行评估。 ==
优先级高于||
只是意味着
true || foo == getValue()
被评估为
true || (foo == getValue())
而不是
(true || foo) == getValue()
如果你只是考虑这种方式的优先级,然后考虑评估总是从左到右(例如, ||
的左操作数总是在右操作数之前进行评估),那么一切都很简单 - 而getValue()
是从未因短路而评估过。
要从等式中消除短路,请考虑以下示例:
A + B * C
...其中A
, B
和C
可以只是变量,或者它们可以是其他表达式,例如方法调用。 在Java中,保证将其评估为:
A
(并记住以后) B
C
B
和C
的结果相乘 A
的结果 请注意,即使*
具有比+
更高的优先级,仍然在B
或C
之前评估A
如果你想在排序方面考虑优先级,请注意在加法之前乘法仍然如何发生 - 但它仍然满足从左到右的评估顺序。
根据语言规范, https://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.24
在运行时,首先计算左侧操作数表达式; 如果结果具有布尔类型,则进行拆箱转换(第5.1.8节)。
如果结果值为true,则条件或表达式的值为true,并且不评估右侧操作数表达式。
所以如果你有a || b==c
a || b==c
,它不被解释为(a || b) == c
,因为||
正如您在教程中找到的那样,优先级较低。 相反,它被解释为a || (b==c)
a || (b==c)
。 现在因为a
是||
的左侧 ,首先评估它。
在这种情况下没有运算符优先级。 你在质疑的是在f(callback)
语句中甚至在f
之前评估的callback
函数。 这不可能发生。
另一方面,在JS中||
是少数几个可以在展会上观看懒惰的地方之一。 ==
操作数(好像它是一个类似于全功能语言的中缀函数)需要两个参数,左边的一个首先得到评估。 如果它解析为true
则第二个参数甚至不会被评估。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.