跳到主要内容

JavaScript 运算符

算数运算

算术运算符包括:加+、减-、乘*、除/、求余运算符%、数值取反运算符-。

这里就不说了,注意数据类型的隐式转换。

与或非

与(&&):有假即假

或(||):有真即真

非(!):取反

也是注意类型的隐式转换

大小比较

大小运算符说明
<如果第一个操作数小于第二个操作数,则返回 true;否则返回 false
<=如果第一个操作数小于或等于第二个操作数,则返回 true;否则返回 false
>=如果第一个操作数大于或等于第二个操作数,则返回 true;否则返回 false
>如果第一个操作数大于第二个操作数,则返回 true;否则返回 false
  1. 如果两个操作数都是数字,或者一个是数值,另一个可以转换成数字,则将根据数字大小进行比较。
  2. 如果两个操作数都是字符串,则执行字符串比较。这个时候 JS 解释器会把字符串转换为 ASCII 码逐个字符依次比较
  3. 如果一个操作数是数字,或者被转换为数字,另一个是字符串,或者被转换为字符串,则使用 parseInt() 将字符串转换为数字(对于非数字字符串,将被转换为 NaN),最后以数字方式进行比较。
  4. 如果一个操作数为 NaN,或者被转换为 NaN,则始终返回 false。
  5. 如果一个操作数是对象,则先使用 valueOf() 取其值,返回值为简单数据类型,转换为数字,为复杂数据类型,则使用 toString() 取其字符串表示,再进行比较。
var a = {};
a.valueOf = function () {
return 10;
}; // 重写了 valueOf 方法
// a.valueOf = function(){ return {name: 1}}
console.log(a > 9);
  1. 如果一个操作数是布尔值,则先转换为数值,再进行比较。
  2. 如果操作数都无法转换为数字或字符串,则比较结果为 false。

相等和不相等

等值检测运算符说明
==(相等)比较两个操作数的值是否相等
!=(不相等)比较两个操作数的值是否不相等
===(全等)比较两个操作数的值是否相等,同时检测它们的类型是否相同
!==(不全等)比较两个操作数的值是否不相等,同时检测它们的类型是否不相同

赋值运算符

赋值运算符说明示例等效于
+=加法运算或连接操作并赋值a += ba = a + b
-=减法运算并赋值a -= ba= a - b
*=乘法运算并赋值a *= ba = a * b
/=除法运算并赋值a /= ba = a / b
%=取余运算并赋值a %= ba = a % b
<<=左移位运算并赋值a <<= ba = a << b
>>=右移位运算并赋值a >>= ba = a >> b
>>>=无符号右移位运算并赋值位a >>>= ba = a >>> b
&=位与运算并赋值a &= ba = a & b
|=位或运算并赋值a |= ba = a |= b
^=位异或运算并赋值a ^= ba = 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