本文介绍了为什么JavaScript中的逻辑运算符保持关联性?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

逻辑AND和OR运算符和三元条件运算符.已针对短路评估,使用以下规则:

The logical AND and OR operators are the only lazy operators in JavaScript along with the ternary conditional operator. They are tested for short-circuit evaluation using the following rules:

false && anything === false
true || anything === true

这与在Haskell中实现的方式相同:

This is the same way it is implemented in Haskell:

(&&) :: Bool -> Bool -> Bool
False && _ = False
True  && x = x

(||) :: Bool -> Bool -> Bool
True  || _ = True
False || x = x

但是根据JavaScript中的MDN逻辑运算符保持关联状态.这是反直观的.以我的拙见,它们应该是正确的联系. Haskell做正确的事. Haskell中的逻辑运算符是正确的关联:

However according to MDN logical operators in JavaScript are left associative. This is counter intuitive. In my humble opinion they should be right associative. Haskell does the right thing. Logical operators in Haskell are right associative:

infixr 3 &&
infixr 2 ||

在Haskell中考虑以下表达式:

Consider the following expression in Haskell:

False && True && True && True

因为&&在Haskell中是正确的关联,所以上面的表达式等效于:

Because && is right associative in Haskell the above expression is equivalent to:

False && (True && (True && True))

因此,表达式(True && (True && True))的计算结果无关紧要.由于有了第一个False,整个表达式只需一步就可以简化为False.

Hence it doesn't matter what the expression (True && (True && True)) evaluates to. Because of the first False the entire expression is reduced to False in a single step.

现在考虑如果&&保持关联状态会发生什么.该表达式将等效于:

Now consider what would happen if && was left associative. The expression would be equivalent to:

((False && True) && True) && True

现在将需要3次缩减才能计算出整个表达式:

It would now take 3 reductions to evaluate the entire expression:

((False && True) && True) && True
(False && True) && True
False && True
False

如您所见,逻辑运算符具有正确的关联性更有意义.这使我想到了我的实际问题:

As you can see it makes more sense for logical operators to be right associative. This brings me to my actual question:

为什么JavaScript中的逻辑运算符保持关联性? ECMAScript规范对此要说些什么? JavaScript中的逻辑运算符实际上是正确的关联吗? MDN文档是否包含有关逻辑运算符关联性的错误信息?

Why are logical operators in JavaScript left associative? What does the ECMAScript specification have to say about this? Are logical operators in JavaScript actually right associative? Does the MDN docs have incorrect information about the associativity of logical operators?

编辑:根据规范逻辑运算符保持关联性:

According to the specification logical operators are left associative:

LogicalANDExpression = BitwiseORExpression
                     | LogicalANDExpression && BitwiseORExpression

LogicalORExpression = LogicalANDExpression
                    | LogicalORExpression || LogicalANDExpression

推荐答案

对于任何体面的编译器而言,这些运算符的选择关联几乎是无关紧要的,无论如何输出的代码都是相同的.是的,分析树是不同的,但是发出的代码不必是这样.

For any decent compiler the chosen associativity of these operators are pretty much irrelevant, and the outputted code will be the same regardless. Yes, the parse tree is different, but the emitted code doesn't need to be.

在我所知道的C家族的所有语言中(Javascript也属于),逻辑运算符保持关联.因此,真正的问题变成了,为什么类似C的语言将逻辑运算符定义为左关联?由于选择的关联性是不相关的(就语义和效率而言),我怀疑是选择了最自然"的关联性(例如大多数其他运算符使用什么"),尽管我没有这样做.没有任何资料来支持我的主张.其他可能的解释是,左关联运算符使用LALR解析器进行解析所占用的堆栈空间更少(如今这已不是大问题,但可能在C出现时又回来了.)

In all of the languages of the C family that I know of (to which Javascript also belongs), the logical operators are left associative. So the real question becomes, why do C-like languages define logical operators as left-associative? Since the chosen associativity is irrelevant (in terms of semantic, and in terms of efficiency), my suspicion is that the most "natural" (as in "what the majority of the other operators use") associativity was chosen, although I don't have any sources to back up my claims. Other possible explanation is that left associative operators take less stack space to parse using an LALR parser (which is not a big concern nowadays, but probably was back when C appeared).

这篇关于为什么JavaScript中的逻辑运算符保持关联性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-25 00:41