在所有的运算里,都是有运算顺序的。小时候学四则运算的时候,我们都知道这么一个规则:先乘除后加减,有括号要先算括号!
同样的,在JavaScript里面,运算符也是有相应的优先级的。其优先级如下表所示,前面的优先级高于后面的
运算符 | 操作 |
++ | 自增(注意前后的区别) |
-- | 自减(注意前后的区别) |
- | 求反(针对数字) |
+ | 转换成数字 |
~ | 按位求反 |
! | 逻辑非 |
delete, typeof, void | 删除属性,检查数据类型,返回undefined的值 |
*, /, % |
乘,除,求余 |
+, - | 加,减 |
+ | 字符串连接 |
<<, >>, >>> | 左移位,有符号的右移位,无符号的右移位 |
<, <=, >, >= | 比较大小,先比数字,后比字母 |
== | 判断是否相等 |
!= | 判断是否不等 |
=== | 判断是否恒等 |
!== | 判断是否不恒等 |
& | 按位与 |
^ | 按位异或 |
| | 按位或 |
&& | 逻辑与 |
|| | 逻辑或 |
?: | 条件运算符 |
= | 赋值运算符 |
op= | 运算且赋值 |
下面举个栗子
var result = 0;
var a = 10;
var b = 20;
var i = 2;
result = a > b ? a + ( b * i++ ) : a + ( b / i--)
console.log(result); // 20
console.log(i); // 1
解释:因为 a>b 并不成立,所以选择第二个表达式 “a + ( b / i-- )”,10 + ( 20 / 2 ) 结果为 20(与此同时,i 进行自减,结果为 1),然后执行赋值语句,result 为 20。
PS:
当自增++(自减--)在操作数前面,操作数进行自增1(自减1)计算,并且返回计算后的值;
当自增++(自减--)在操作数后面,操作数进行自增1(自减1)计算,并且返回计算前的值;
var i = 1;
var j = ++i;
var m = 1;
var n = m++;
console.log(i); // 2
console.log(j); // 2
console.log(m); // 2
console.log(n); // 1
扩展:有个蛋疼的面试题如下
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}}