JavaScript 运算符
算数运算
算术运算符包括:加+、减-、乘*、除/、求余运算符%、数值取反运算符-。
这里就不说了,注意数据类型的隐式转换。
与或非
与(&&):有假即假
或(||):有真即真
非(!):取反
也是注意类型的隐式转换
大小比较
大小运算符 | 说明 |
---|---|
< | 如果第一个操作数小于第二个操作数,则返回 true;否则返回 false |
<= | 如果第一个操作数小于或等于第二个操作数,则返回 true;否则返回 false |
>= | 如果第一个操作数大于或等于第二个操作数,则返回 true;否则返回 false |
> | 如果第一个操作数大于第二个操作数,则返回 true;否则返回 false |
- 如果两个操作数都是数字,或者一个是数值,另一个可以转换成数字,则将根据数字大小进行比较。
- 如果两个操作数都是字符串,则执行字符串比较。这个时候 JS 解释器会把字符串转换为 ASCII 码逐个字符依次比较
- 如果一个操作数是数字,或者被转换为数字,另一个是字符串,或者被转换为字符串,则使用 parseInt() 将字符串转换为数字(对于非数字字符串,将被转换为 NaN),最后以数字方式进行比较。
- 如果一个操作数为 NaN,或者被转换为 NaN,则始终返回 false。
- 如果一个操作数是对象,则先使用 valueOf() 取其值,返回值为简单数据类型,转换为数字,为复杂数据类型,则使用 toString() 取其字符串表示,再进行比较。
var a = {};
a.valueOf = function () {
return 10;
}; // 重写了 valueOf 方法
// a.valueOf = function(){ return {name: 1}}
console.log(a > 9);
- 如果一个操作数是布尔值,则先转换为数值,再进行比较。
- 如果操作数都无法转换为数字或字符串,则比较结果为 false。
相等和不相等
等值检测运算符 | 说明 |
---|---|
==(相等) | 比较两个操作数的值是否相等 |
!=(不相等) | 比较两个操作数的值是否不相等 |
===(全等) | 比较两个操作数的值是否相等,同时检测它们的类型是否相同 |
!==(不全等) | 比较两个操作数的值是否不相等,同时检测它们的类型是否不相同 |
赋值运算符
赋值运算符 | 说明 | 示例 | 等效于 |
---|---|---|---|
+= | 加法运算或连接操作并赋值 | 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 |
<<= | 左移位运算并赋值 | 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 |
^= | 位异或运算并赋值 | a ^= b | a = a ^ b |
逻辑位运算符
位运算就是对二进制数执行计算,是整数的逐位运算。例如,1+1=2,在十进制计算中是正确的,但是在二进制计算中,1+1=10;对于二进制数 100 取反,等于 001,而不是 -100。
位运算符有 7 个,分为两类:
- 逻辑位运算符:位与(&)、位或(|)、位异或(^)、非位(~)
- 移位运算符:左移(<<)、右移(>>)、无符号右移(>>>)
位与(&):将比较的俩个操作转换为 2 进制将每一位进行比较,都是 1 为 1,有 0 即 0,,然后将对应位的结果拼接,在转换为 10 进制。
var num = 13;
num.toString(2); // 1101
var num = 3;
num.toString(2); // 0011
13 & 3; // 0001 => 1
13 & 1; // 0001 => 1
位或(|):有 1 为 1
var num = 13;
num.toString(2); // 1101
var num = 3;
num.toString(2); // 0011
13 | 3; // 1111 => 15
位异或(^):用于对两个二进制操作数逐位进行比较。(减法的底层就是位异或)解释:2 个数的位值相同时为 0,不同时为 1
var num = 13;
num.toString(2); // 1101
var num = 3;
num.toString(2); // 0011
13 ^ 3; // 1110 => 14
非位(~):用于对一个二进制操作数逐位进行取反操作。
第 1 步:把运算数转换为 32 位的二进制整数。
第 2 步:逐位进行取反操作。
第 3 步:把二进制反码转换为十进制浮点数。
~12;
/*
1. 0000 0000 0000 0000 0000 0000 0000 1100(12)
2. => 按位取反
1111 1111 1111 1111 1111 1111 1111 0011
3. 发现符号位(即最高位)为1(表示负数),将除符号位之外的其他数字取反 =>
1000 0000 0000 0000 0000 0000 0000 1100
4. 末位加1取其补码 =>
1000 0000 0000 0000 0000 0000 0000 1101
5. 转换回十进制 => -13
*/
移位运算符
移位运算就是对二进制进行有规律低移位。移位运算可以设计很多奇妙的效果,在图形图像编程中应用广泛。
左移位运算(“<<”)
// 把数字 5 向左移动 2 位,则返回值为 20。
(5 <<
(2 - // 101(5) => 10100(20)
1000)) <<
8; // -256000
1000 << 8; // 256000
右移位运算(“>>”)
符号右移位运算,与左移运算操作相反,它把 32 位数字中的所有有效位整体右移,再使用符号位的值填充空位。移动过程中超出的值将被丢弃。
// 把数字 1000 向左移动 8 位,则返回值为 3。
(1000 >>
(8 - // 1111101000(1000) => 11(3)
1000)) >>
8; // -4
无符号右移位运算(“>>>”)
“>>>”运算符执行无符号右移位运算。它把无符号的 32 位整数所有数位整体右移。对于无符号数或正数右移运算,无符号右移与有符号右移运算的结果是相同的。
对于负数来说,无符号右移将使用 0 来填充所有的空位,同时会把负数作为正数来处理,所得结果会非常大所以,使用无符号右移运算符时要特别小心,避免意外错误。
console.log(1000 >> 8); //返回值3
console.log(-1000 >> 8); //返回值 -4
/*
0000 0000 0000 0000 0000 0011 1110 1000 (1. 无符号整数)
1111 1111 1111 1111 1111 1100 0001 0010 (2. -1000的表示,第一步求反+1)
1111 1111 1111 1111 1111 1111 1111 1100 (3. 带符号位移,使用符号位的值填充空位)
0000 0000 0000 0000 0000 0000 0000 0100 (4. 第三步取反 +1)
1000 0000 0000 0000 0000 0000 0000 0100 (5. 符号位补1)答案是-4
*/
console.log(1000 >>> 8); //返回值3
console.log(-1000 >>> 8); //返回值 16777212
/*
0000 0000 0000 0000 0000 0011 1110 1000 (1. 无符号整数)
1111 1111 1111 1111 1111 1100 0001 0010 (2. -1000的表示,第一步求反+1)
0000 0000 1111 1111 1111 1111 1111 1100 (3. 无符号位移) => 16777212
*/
用位运算提升效率
// | 取整
let num1 = 7;
num1 = num1 | 0;
// >> 取半
let num2 = 6;
num2 = num2 >> 1; // 3
// << 加倍
let num3 = 6;
num3 = num3 << 1; // 12
// ^ 交换值
let num4 = 10;
let num5 = 20;
num4 ^= num5;
num5 ^= num4;
num4 ^= num5; // num4 === 2, num5 === 1
// & 判断奇数
let num6 = 10;
let num7 = 11;
num6 & (1 === 1); // true
num7 & (1 === 1); // false
// ~ 判断是否存在
const data = '123456';
const key = '3';
const keyIsExist = !!~data.indexOf(key); // true
// 是否 2 的整数幂
const isPowerOf2 = num => (num & (num - 1)) === 0;
isPowerOf2(8); // true
isPowerOf2(7); // false