在所有的运算里,都是有运算顺序的。小时候学算术运算的时候,我们都知道这么一个规则:先乘除后加减,有括号要先算括号!
同样的,在JavaScript里面,运算符的优先级如下表所示,前面的优先级高于后面的
运算符 | 操作 |
++ | 自增(注意前后的区别) |
-- | 自减(注意前后的区别) |
- | 求反(针对数字) |
+ | 转换成数字 |
~ | 按位求反 |
! | 逻辑非 |
delete, typeof, void | 删除属性,检查数据类型,返回undefined的值 |
*, /, % |
乘,除,求余 |
+, - | 加,减 |
+ | 字符串连接 |
<<, >>, >>> | 左移位,有符号的右移位,无符号的右移位 |
<, <=, >, >= | 比较大小,先比数字,后比字母 |
== | 判断是否相等 |
!= | 判断是否不等 |
=== | 判断是否恒等 |
!== | 判断是否不恒等 |
& | 按位与 |
^ | 按位异或 |
| | 按位或 |
&& | 逻辑与 |
|| | 逻辑或 |
?: | 条件运算符 |
= | 赋值运算符 |
op= | 运算且赋值 |
下面举个栗子
var a = {n: 1}; var b = a; a.x = a = {n: 2}; console.log(a.x); // undefined console.log(b.x); // {n: 2} // a => {n: 2} // b => { // n: 1, // x: {n: 2 } // }
解析:
虽然赋值运算符是从右到左计算,但是这里也有一个很重要的考点:运算符的优先级
.点号运算 优于 =赋值运算,因此 a.x = a = {n: 2} 可以理解为:
1). 声明a对象中的x属性,而此时b和a同时指向对象{n: 1, x: undefined},即同时拥有未赋值的x
2). 从右至左开始赋值
1>. 对 a对象 赋值 -- a = {n: 2},此时变量名a改变指向 到 新对象{n: 2}
2>. 对 a.x(可以理解为b.x,就是说a.x已经确定了指向,因此不会受到1>步的影响) 属性赋值{n: 2},此时对象b -> {n:1, x:{n:2}}