JavaScript常见的运算符优先级面试题

1,290 阅读4分钟

这是我参与11月更文挑战的第1天,活动详情查看:2021最后一次更文挑战

小试牛刀

来看看这样一道题目

console.log(true || false && false)

返回的是什么?

到底是true还是false

如果你对这道题目是一知半解的,那么这篇文章很适合你!


前言

运算符优先级的知识点真的很重要,例如如何判断 && || 的运算优先级。如果你不能掌握这些基础知识点。你甚至算不上一个初级程序员。

在学校或是培训机构,老师只会告诉你,() 括号运算符的优先级最高。在不能判断运算符优先级顺序的时候,使用 () 。这确实是个好办法,但作为有上进心的有为青年,一定要学会判断运算符优先级。

基础

计算机编译程序是从左往右的,但是运算符却不尽然。这里有一个知识点,叫做关联性。

关联性

关联性是运算符优先级里很重要的一个概念,它决定了拥有相同优先级的运算符的执行顺序。

通常有三种关联性,分别为左关联右关联无关联

a OP b OP c; 左关联(左到右)相当于把左边的子表达式加上小括号(a OP b) OP c,右关联(右到左)相当于a OP (b OP c)

参考文献

取自 MDN web docs

优先级 运算类型 关联性 运算符
21 圆括号 n/a(不相关) ( … )
20 成员访问 从左到右 … . …
需计算的成员访问 从左到右 … [ … ]
new (带参数列表) n/a new … ( … )
函数调用 从左到右 … ( … )
可选链(Optional chaining) 从左到右 ?.
19 new (无参数列表) 从右到左 new …
18 后置递增(运算符在后) n/a
 
… ++
后置递减(运算符在后) … --
17 逻辑非 从右到左 ! …
按位非 ~ …
一元加法 + …
一元减法 - …
前置递增 ++ …
前置递减 -- …
typeof typeof …
void void …
delete delete …
await await …
16 从右到左 … ** …
15 乘法 从左到右
 
… * …
除法 … / …
取模 … % …
14 加法 从左到右
 
… + …
减法 … - …
13 按位左移 从左到右 … << …
按位右移 … >> …
无符号右移 … >>> …
12 小于 从左到右 … < …
小于等于 … <= …
大于 … > …
大于等于 … >= …
in … in …
instanceof … instanceof …
11 等号 从左到右
 
… == …
非等号 … != …
全等号 … === …
非全等号 … !== …
10 按位与 从左到右 … & …
9 按位异或 从左到右 … ^ …
8 按位或 从左到右 … | …
7 逻辑与 从左到右 … && …
6 逻辑或 从左到右 … || …
5 空值合并 从左到右 … ?? …
4 条件运算符 从右到左 … ? … : …
3 赋值 从右到左 … = …
… += …
… -= …
… **= …
… *= …
… /= …
… %= …
… <<= …
… >>= …
… >>>= …
… &= …
… ^= …
… |= …
… &&= …
… ||= …
… ??= …
2 yield 从右到左 yield …
yield* yield* …
1 展开运算符 n/a ... …
0 逗号 从左到右 … , …

实际应用的坑

&&与||

看如下代码

 console.log(true || false && false) // true

这是一个很经典的例子,如果我们不知道 && 的优先级比 || 高,我们肯定以为返回值是false


三元运算符和==

let value = "3"
let index = 3
let flag = value == index ? 1 : 2
console.log(flag) // 1

等号(==)和全等号(===)的优先级是比三目运算符更高的。所以要先算前面的value == index,返回值是true。最终结果为1

如果三目运算符的优先级比等号高,那结果将会完全相反。返回值将会是false


加减乘除和取模

console.log(1 + 2 * 3 % 4) // 3

先算乘除和取模再算加减。

tip:乘除和取模的运算符优先级是一样的,所以从左到右开始计算。


前置递减、前置递增和&&

let number = 1
console.log(--number && 7) // 0
let number2 = 0
console.log(++number2 && 7) // 7

前置递减、前置递增的运算符优先级比&&高,先算递减


typeof和三元运算符

let flag = false
console.log(typeof flag) // boolean
console.log(typeof flag ? '2' : 1) // 2

typeof的计算运算级比三元运算符高,所以返回的是2。


加减乘除和大小于

let number = 3
console.log(number + 4 > 6) // true
console.log(number * 2 > 5) // true

加减乘除的运算符优先级比大小于高,先计算加减乘除


&&和三元运算符

console.log(1 && 0 ? 3 : 2) // 2

&&的运算级比三元运算符更高,先计算&&


总结

运算符优先级是很大一个模块,它的难度非常高!

大家一定要多花时间研究研究。