运算符的综合运算顺序是:非运算符 > 算术运算符 > 比较运算符 > 逻辑运算符。
3 > 2 && 8 > 3 + 4 // true。首先计算 3 + 4 等于 7;然后比较 3 > 2 为 true;再比较 8 > 7 为 true;最后 true && true;结果为 true
!13 < 5 - 3 // true。首先 13 为 true,!13 就为 false;然后计算 5 -3 等于 2;最后比较 false < 2,false 隐式转换为 0,0 < 2 为 true
算数运算符:
加+
、减-
、乘*
、除/
、取余%
。
加号 +
有加法和连字符两种作用。
加法运算时,如果有一个操作数是字符串,则将另外的操作数转换为字符串,然后再将两个字符串拼接起来。
var num1 = 10;
var num2 = 5;
var result1= ”num is” + num1 + num2; // num is 105
var result2 = ”num is” + (num1 + num2); // num is 15
被除数 ÷ 除数 = 商
除法运算时,正数除以 0,返回 infinity;负数除以 0,返回 -infinity;0 除以 0,返回 NaN。
console.log(1 + 5 % 3); // 3
console.log((1 + 5) % 3); // 0
如果参与数学运算的某操作数不是数字类型,那么 JavaScript 会自动将此操作数转换为数字类型(除了加法运算符中有操作数为字符串的情况),隐式类型转换的本质是内部调用了 Number()。
console.log(3 * '4'); // 12
console.log(true + true); // 2
console.log(3 * '2天'); // NaN
算术运算符的运算顺序:
默认情况下,乘法、除法和取余的优先级要高于加法和减法,必要时可以使用圆括号来改变运算的顺序。
比较运算符/关系运算符:
比较运算符的表达式的结果为布尔值。
-
小与<
、大于>
、小与等于<=
、大于等于>=
。
当比较运算符的操作数使用了非数值时,要进行数据转换。如果一个操作数是数值,则将另一个操作数转换为数值。如果两个操作数都是字符串,则比较两个字符串对应的字符编码值。
JS 中没有连比。
例如:想要变量 num 的值为 100, 想要判断 num 是否是介于 3 到 15 之间。
// 错误
console.log(3 <= num <= 15); // true。因为先判断 3 <= num,结果为 true;再判断 true <= 15,true 被转换为 1,所以结果为 true
// 正确
console.log(num >= 3 && num <= 15)
-
==
:相等,只根据表面值进行判断,不判断数据类型,会进行隐式类型转换。
===
:全等,不仅判断表面值,还要判断数据类型。
!=
:不相等,只根据表面值进行判断,不判断数据类型,会进行隐式类型转换。
!==
:不全等,不仅判断表面值,还要判断数据类型。
console.log(0 == false); // true
console.log(0 === false); // false
console.log(undefined == null); // true
console.log(undefined === null); // false
逻辑运算符:
-
!
:逻辑非。逻辑非运算符可以应用于任何类型的操作数,只需要一个操作数,会首先将它的操作数转换为布尔值,然后再对其求反。
逻辑非运算符的表达式的结果总是一个布尔值。
同时使用两个逻辑非操作符,实际上就会模拟 Boolean() 转型函数的行为。
console.log(!''); // true
-
&&
:逻辑与。逻辑与运算符可以应用于任何类型的操作数,只有当两个操作数的值都为 true 的时候,结果才为 true(都真才真)。
如果第一个操作数为 true,那么逻辑与运算符的表达式的结果为第二个操作数;如果第一个操作数为 false,那么逻辑与运算符的表达式的结果为第一个操作数。
逻辑与操作属于短路计算,如果第一个操作数是 false,则无论第二个操作数是什么值,都不会再对其进行求值。
console.log('哈哈' && 0); // 0。’哈哈‘ 为真,返回第二个操作数
console.log(0 && '哈哈'); // 0。0 为假,直接返回第一个操作数
var a = ture;
var result = (a && b); // 发生错误,b 未声明
console.log(result); // 不会执行
var a = false;
var result = (a && b); // 不会发生错误
console.log(result); // 执行
-
||
:逻辑或。逻辑或运算符可以应用于任何类型的操作数,只要两个操作数有一个是 true,则结果为 true(有真就真)。
如果第一个操作数为 true,那么逻辑或运算符的表达式的结果为第一个操作数;如果第一个操作数为 false,那么逻辑或运算符的表达式的结果为第二个操作数。
逻辑或运算符属于短路计算,如果第一个操作数是 true,则无论第二个操作数是什么值,都不会再对其进行求值。
逻辑运算符的运算顺序:
逻辑运算符的优先级为:逻辑非的优先级大于逻辑与,逻辑与的优先级大于逻辑或(非 > 与 > 或)。
优先级高不是先执行的意思,可以理解为给它加个括号,使其成为一个整体。执行顺序还是从左到右。
function a(){
console.log("a");
return true;
}
function b(){
console.log("b");
return false;
}
function c(){
console.log("c");
return true;
}
a() || b() && c(); // a。相当于 a() || (b() && c()),a() 返回 true 为真,后面的表达式就不再执行了
赋值运算符:
赋值运算符的表达式的结果为等号后面的值。
console.log(num = 4); // 4
这就意味着,可以连续使用赋值运算符。
var num, num1;
num = num1 = 15; // 会从右到左进行赋值。先将 15 赋值给 num1;numi = 15 这个表达式的结果也为 15;载将这个结果赋值给 num
console.log(num); // 15
console.log(num1); // 15
- 简单赋值运算符:将等号右边的数值,赋值给等号左边的变量。
var userName = ”tom”;
- 复合赋值运算符:
a += b; // 就相当于 a = a + b;
a -= b; // 就相当于 a = a - b;
a *= b; // 就相当于 a = a * b;
a /= b; // 就相当于 a = a / b;
a %= b; // 就相当于 a = a % b;
- 自增运算符
++
、自减运算符 --
:表示在自身的基础上加 1 或者减 1。分为前置型和后置型。
前置型:操作符位于要操作的变量之前。前置型先加后用。
后置型:操作符位于要操作的变量之后。后置型先用后加。i = 1;
j = i++; // 结果为 j = 1,i = 2。因为先用后加,先 i 等于 1 的时候赋值给 j,然后 i = i + 1 = 2
I = 1;
j = ++i; // 结果为 j = 2,i = 2。因为先加后用,先 i = i + 1 = 2,然后将 2 赋值给 j
赋值运算符的运算顺序:
自增、自减运算符大于其他的赋值运算符。
三元运算符/三目运算符/条件运算符:
三元运算符的语法:条件表达式 ?表达式1 :表达式2;
。如果条件表达式的结果为 true,则执行表达式 1;如果为 false,则执行表达式 2。
三元运算符的用途:根据某个条件是否从成立,在两个表达式或者值中选择其中一个。
var num = 10;
num >= 5 ? console.log('大了') : console.log('小了')
var age = 24
var type = age >= 18 ? '成年人' : '未成年人'
位运算符:
位运算符处理32位数。如果对非数值进行位运算,会先自动使用Number()函数将该值转换为一个数值,然后再进行位运算。在对NaN和Infinity值进行位运算时,会被当成0来处理。
在javascript内部,数值都是以64位浮点数的形式存储的。
当对数值做位运算的时候,是以32位带符号的整数进行运算的。也就是说,如果操作数不是整数,则会自动转成整数后再执行。
后台会发生如下转换过程:64位的数值被转换成32位数值,然后执行位运算,最后再将32位的结果转换回64位的数值。
有符号整数使用32位中的前31位表示整数数值,用第32位表示整数符号,0表示正数,1表示负数,这个表示符号的位叫做符号位。
例如:数值18的二进制表示是00000000000000000000000000010010,或者更简洁的10010。这是5个有效位,这5位本身就决定了实际的值。
负数同样也以二进制存储,但使用的格式是二进制补码。计算一个数值的二进制补码,要经过下列三个步骤:求这个数值绝对值的二进制码;求二进制反码,即将0替换成1,1替换成0;得到的二进制反码加1。
例如:要得到-18的二进制表示,首先要得到18的二进制表示:0000 0000 0000 0000 0000 0000 0001 0010;接下来,计算二进制反码:1111 1111 1111 1111 1111 1111 1110 1101;最后,在二进制反码上加上1;
二进制转十进制:从右向左依次是第0.1.2…位,第n位的数值(0或1)乘以2的n次方得到的数值相加就是结果。
位运算符直接处理每一个比特位,所以是非常底层的运算。
优点:运算速度极快。
缺点:运算很不直观,许多场合不能使用,否则会使代码难以理解和查错。
-
按位非~:返回数值的反码,即将0替换成1,1替换成0。按位非的本质是操作数的负值减1。
var num1=25;//00000000000000000000000000011001
var num2=~num1;//11111111111111111111111111100110
alert(num2);//-26
-
按位与&:只有两个操作数的对应位都是1,该位才是1,否则该位是0。
-
按位或|:只要两个操作数的对应位有一个是1,该位就是1,只有两个操作数的对应位都是0 ,该位才是0。
-
按位异或^
:只有两个操作数的对应位只有一个为1时,该位才为1,都为0或都为1时,该位为0。
-
按位左移a<<b:把a的所有位向左移动b所指定的位数,用0来填充右边空出的位。左移不会影响操作数的符号位。
-
按位右移a>>b:把a的所有位向右移动b指定的位数,从右边移出去的位被丢弃,左边空出的位补符号位。
如果要移走的值为负数,每一次右移左边的空位补1;如果要移走的值为正数,每一次右移左边的空位补0,这叫做符号位扩展,或者保留符号位。
-
按位无符号右移a>>>b:把a的所有位向右移b指定的位数,向右移出的位被丢弃,左边空出的位用零来填充。
逗号运算符:
多用于声明多个变量;还可以用于赋值,在用于赋值时,总会返回表达式的最后一项。
var num1=1,num2=2,num3=3;
var num=(1,2,3); // num=3