逻辑 AND 和 OR 运算符是 JavaScript 中唯一的惰性运算符以及三元条件运算符。使用以下规则对它们进行短路评估测试:
false && anything === false
true || anything === true
这与在 Haskell 中实现的方式相同:
(&&) :: Bool -> Bool -> Bool
False && _ = False
True && x = x
(||) :: Bool -> Bool -> Bool
True || _ = True
False || x = x
然而,根据 MDN,JavaScript 中的逻辑运算符是左关联的。这是反直觉的。在我看来,他们应该是正确的联想。Haskell 做了正确的事。Haskell 中的逻辑运算符是右结合的:
infixr 3 &&
infixr 2 ||
考虑 Haskell 中的以下表达式:
False && True && True && True
因为&&
在 Haskell 中是右结合的,所以上面的表达式等价于:
False && (True && (True && True))
因此,表达式的结果并不重要(True && (True && True))
。因为第一个False
,整个表达式被简化为False
一步。
现在考虑如果&&
留下联想会发生什么。该表达式将等效于:
((False && True) && True) && True
现在需要 3 次归约来评估整个表达式:
((False && True) && True) && True
(False && True) && True
False && True
False
如您所见,逻辑运算符具有右关联性更有意义。这让我想到了我的实际问题:
为什么 JavaScript 中的逻辑运算符是左关联的?ECMAScript 规范对此有什么看法?JavaScript 中的逻辑运算符实际上是右关联的吗?MDN 文档是否有关于逻辑运算符关联性的错误信息?
编辑:根据规范,逻辑运算符是左关联的:
LogicalANDExpression = BitwiseORExpression
| LogicalANDExpression && BitwiseORExpression
LogicalORExpression = LogicalANDExpression
| LogicalORExpression || LogicalANDExpression