为什么 && 比 || 优先级高?
起因
偶然在网上搜索 js 运算符优先级,几乎每个版本都告诉读者 &&
比 ||
优先级更高,包括 MSN 这样的权威网站也不例外。
这与自己经验不符 —— 它们应该是优先级一样的。
论证
0 || 1 && 0 || 2
// 按 && 优先级高
( 0 || ( 1 && 0 ) ) || 2
// 按优先级一致
0 || ( 1 && ( 0 || 2 ) )
无论怎么执行结果都一样
诡辩
因为有 MDN 背书,中英文版本都是一样,心想这事情不会那么简单。于是,打开 ES 规范来找寻真相。
12.13 Binary Logical Operators
Syntax
LogicalANDExpression[In, Yield, Await] :
- BitwiseORExpression [?In, ?Yield, ?Await]
- LogicalANDExpression [?In, ?Yield, ?Await] && BitwiseORExpression [?In, ?Yield, ?Await]
LogicalORExpression[In, Yield, Await]:
- LogicalANDExpression [?In, ?Yield, ?Await]
- LogicalORExpression [?In, ?Yield, ?Await] || LogicalANDExpression [?In, ?Yield, ?Await]
细细品品以上定义,会发现逻辑或表达式包含逻辑与表达式。再来看看的求值过程:
12.13.3 Runtime Semantics: Evaluation
LogicalANDExpression : LogicalANDExpression && BitwiseORExpression
- Let lref be the result of evaluating LogicalANDExpression.
- Let lval be ? GetValue(lref).
- Let lbool be ToBoolean(lval).
- If lbool is false, return lval.
- Let rref be the result of evaluating BitwiseORExpression.
- Return ? GetValue(rref).
LogicalORExpression : LogicalORExpression || LogicalANDExpression
- Let lref be the result of evaluating LogicalORExpression.
- Let lval be ? GetValue(lref).
- Let lbool be ToBoolean(lval).
- If lbool is true, return lval.
- Let rref be the result of evaluating LogicalANDExpression.
- Return ? GetValue(rref).
回看开始的例子里的语句 0 || 1 && 0 || 2
- 根据定义这是一条逻辑或表达式
- 执行逻辑等价于
( 0 || ( 1 && 0 ) ) || 2
这么理解,就符合 && 优先级更高的说法。
总结
来个复杂点的
0 || 1 && 0 || 2 && 3 && 0 || 1 && 0
按照规范来执行
( ( 0 || ( 1 && 0 ) ) || ( 2 && 3 && 0 ) ) || ( 1 && 0 )
将两者理解成不区分优先级,从左到右执行
0 || ( 1 && ( 0 || ( 2 && ( 3 && ( 0 || ( 1 && 0 ) ) ) ) ) )
所以,理论上是 && 优先级更高,但是,使用时可以用等价方式。