这是我参与更文挑战的第19天,活动详情查看: 更文挑战
前面的文章,我们回顾了很多操作符,比如用来运算的乘性操作符操作符、加性操作符,用来比较的关系操作符、相等操作符等,相信很多同学都无数次的在学习和工作中用到他们,但是大家有没有好好的想过他们的优先级?是不是仔细一想不知道?工作用用到了再说?不确定优先级,全屏直觉来?有心总结一下,但总是没时间?那不妨来看一下我对操作符优先级的总结。
相同类型操作符
其实在js中和我们数学运算时候一样,也是从左向右进行计算,所以在操作符相同的时候,按从左到右的顺序计算。这里拿上上一节我们用过的一个例子举例
let a = 10
5 < a < 6 // true
还记得我们当时怎么解释的吗?其实就是因为js计算的先后顺序问题,在这个表达式中,由于变量a前后的操作符一样,所以优先级也一样,遵从从左向右的计算规则,于是先计算 5 < a ,然后返回 true,接着拿结果true进行接下来的运算,和6对于,true < 6 成立,返回结果为true。
请注意,前面说的操作符相同,指的是他们的分类相同,并不是字面量的相同,比如同属加性操作符的+、-,同属乘性操作符的*、/、%。
let a = 10
5 < a > 6 // false
不过有时候我们也会遇到一些看似疑惑的事情。例如
let a = 10 = 11 // Uncaught SyntaxError: Invalid left-hand side in assignment
上面的表达式会报错:赋值中的左侧无效,并且最终a的值等于10,有些朋友会问了,不是同类操作符遵从从左到右的顺序进行操作吗?那a不应该是先等于10再等于11吗?其实这是理解上的错误,仔细想想我们就会知道,js先计算a = 10,a = 10会返回一个undefined,接下来会计算undefined = 11,我们知道,我们是不能修改原始类型的值的,所以就会报错咯。
当然啦,也不是所有的同类型的操作符都是遵从从左到右的运算规则的,比如一元运算符中的取反操作符。它遵从的规则是从右到左,即离目标数据最近的取反操作符先生效。例如
let a = !!10
console.log(a) // true
上面的表达式中,先由离10最近的取反操作符将10转化为false,然后由第一个取反操作符再将false转化为true,取反操作符也是为数不多的可以连续使用两个的操作符。
不同类型的操作符
不同类型的操作符优先级如下表所示,大家可以收藏参考一下。
| 优先级 | 运算类型 | 关联性 | 运算符 |
|---|---|---|---|
| 20 | 圆括号 |
n/a | ( … ) |
| 19 | 成员访问 |
从左到右 | … . … |
需计算的成员访问 |
从左到右 | … [ … ] |
|
new (带参数列表) |
n/a | new … ( … ) |
|
| 18 | 函数调用 | 从左到右 | … ( … ) |
| new (无参数列表) | 从右到左 | new … |
|
| 17 | 后置递增(运算符在后) | n/a | … ++ |
| 后置递减(运算符在后) | n/a | … -- |
|
| 16 | 逻辑非 | 从右到左 | ! … |
| 按位非 | 从右到左 | ~ … |
|
| 一元加法 | 从右到左 | + … |
|
| 一元减法 | 从右到左 | - … |
|
| 前置递增 | 从右到左 | ++ … |
|
| 前置递减 | 从右到左 | -- … |
|
| typeof | 从右到左 | typeof … |
|
| void | 从右到左 | void … |
|
| delete | 从右到左 | delete … |
|
| 15 | 幂 | 从右到左 | … ** … |
| 14 | 乘法 | 从左到右 | … * … |
| 除法 | 从左到右 | … / … |
|
| 取模 | 从左到右 | … % … |
|
| 13 | 加法 | 从左到右 | … + … |
| 减法 | 从左到右 | … - … |
|
| 12 | 按位左移 | 从左到右 | … << … |
| 按位右移 | 从左到右 | … >> … |
|
| 无符号右移 | 从左到右 | … >>> … |
|
| 11 | 小于 | 从左到右 | … < … |
| 小于等于 | 从左到右 | … <= … |
|
| 大于 | 从左到右 | … > … |
|
| 大于等于 | 从左到右 | … >= … |
|
| in | 从左到右 | … in … |
|
| instanceof | 从左到右 | … instanceof … |
|
| 10 | 等号 | 从左到右 | … == … |
| 非等号 | 从左到右 | … != … |
|
| 全等号 | 从左到右 | … === … |
|
| 非全等号 | 从左到右 | … !== … |
|
| 9 | 按位与 | 从左到右 | … & … |
| 8 | 按位异或 | 从左到右 | … ^ … |
| 7 | 按位或 | 从左到右 | … | … |
| 6 | 逻辑与 | 从左到右 | … && … |
| 5 | 逻辑或 | 从左到右 | … || … |
| 4 | 条件运算符 | 从右到左 | … ? … : … |
| 3 | 赋值 | 从右到左 | … = … |
… += … |
|||
… -= … |
|||
… *= … |
|||
… /= … |
|||
… %= … |
|||
… <<= … |
|||
… >>= … |
|||
… >>>= … |
|||
… &= … |
|||
… ^= … |
|||
… |= … |
|||
| 2 | yield | 从右到左 | yield … |
| yield* | 从右到左 | yield* … |
|
| 1 | 展开运算符 | n/a | ... … |
| 0 | 逗号 | 从左到右 | … , … |
以上内容引自GitHub,真实性请自行辨别
愉快的一天又结束了,祝大家有个好梦,晚安。