逻辑运算符与三元运算符的优先级

1,930 阅读2分钟

逻辑运算符与三元运算符的优先级

上图:优先级越大数字越大,图片来源 MDN。


关于 JS 中的大多数运算,我想我们都不够陌生,而且看到了就能知道运算顺序。比如(优先级由高到低):一元大于二元大于三元,先乘除后加减,有括号先算括号里面的。

今天聚焦的逻辑运算符和三元运算符的优先级。

一般情况下,很少有人让逻辑运算符的且(&&)和或(||)一起出现,但是它们一旦一起出现,我想大多数人在不查询文档情况下,肯定以为他们是同一优先级,所以依次从左往右执行。但很不幸 && 比 || 的执行优先级高一级,类比下四则运算:&& 就像乘除,|| 就像加减。

比如如下代码:

const foo =  a || b || c && d;

真正的元素规则为:

const foo =  a || b || (c && d);

并不是从左往右,所以两者同时出现一定要加括号,指定运算优先级。

逻辑运算符如果结合三元运算符也是一大困惑,比如如下代码。

const n = a || b ? 1 : 2;

我们往往会把三元当做一个整体看,认为它的运算逻辑为:

const n = a || (b ? 1 : 2);

但实际上三元的运算优先级比逻辑低一级,所以真正的优先级为:

const n = (a || b) ? 1 : 2;

同理当逻辑运算符与三元运算符一起出现,一定要加括号指定运算优先级。

当然,我们是人,很容易忘记一些事情比如不加括号,所以加括号这件事情就交给程序去办吧,利用 ESLint 的 no-mixed-operators 规则可以轻松办到:

{
  "no-mixed-operators": [
    "error",
    {
      "groups": [
        ["+", "-", "*", "/", "%", "**"],
        ["&", "|", "^", "~", "<<", ">>", ">>>"],
        ["==", "!=", "===", "!==", ">", ">=", "<", "<="],
        ["&&", "||", "?:"],
        ["in", "instanceof"]
      ],
      "allowSamePrecedence": true
    }
  ]
}

no-mixed-operators 关于逻辑运算符的默认值为 ["&&", "||"],在这里面加个三元符号就行了 ["&&", "||", "?:"]

可以使用 ESLint 的 playground 测试:

点击查看结果 逻辑运算符与三元运算符的优先级

文档灵感来源:fix: always use github link