运算符号
算术运算符
算术运算符以二个数值(字面量或变量)作为操作数,并返回单个数值。
| + | 加法运算符 | 1 + 1 = 2 | 
| - | 减法运算符 | 2 - 1 = 1 | 
| * | 乘法运算符 | 1 * 2 = 2 | 
| / | 除法运算符 | 2 / 1 = 2 | 
| % | 取余运算符 | 10 % 3 = 1 | 
| ** | 指数运算符 | 2 ** 3 = 8 | 
自增自减运算符
•前置运算符,先自加或者自减,再返回值
•后置运算符,先返回值,后自加或者自减
| A++ | 后置自增运算符 | var a = 0; var b = a++ + 1 console.log(a) // 1 console.log(b) // 1 | 
| A-- | 后置自减运算符 | var a = 0; var b = a-- + 1 console.log(a) // -1 console.log(b) // 1 | 
| ++A | 前置自增运算符 | var a = 0; var b = ++a + 1 console.log(a) // 1 console.log(b) // 2 | 
| --A | 前置自减运算符 | var a = 0; var b = --a + 1 console.log(a) // -1 console.log(b) // 0 | 
一元运算符
一元运算符只有一个操作数。
| delete | 删除对象属性 | const o = { a: 1, b: 2 } delete o.a; | 
| void | 主要用于返回undefined | <a href="javascript:void(0);"> 这个链接点击之后不会做任何事情 </a> <a href="javascript:void(document.body.style.backgroundColor='green');"> 点击这个链接会让页面背景变成绿色。 </a> | 
| typeof | 判断给定对象的类型 | typeof(1) -> number | 
| + | 一元加运算符将操作转换为 Number 类型 | const a = + ''; console.log(a); // 0 | 
| - | 一元减运算符将操作转换为 Number 类型并取反 | const a = - '4'; console.log(a); // -4 | 
| ! | 逻辑非运算符 | const a = ! '4'; console.log(a); // false | 
关系运算符
比较运算符比较两个操作数并返回基于比较结果的布尔值。
| in | 如果指定的属性在指定的对象或其原型链中,则 in 运算符返回 true。 | const car = { make: 'Honda', model: 'Accord' }; console.log('make' in car); // true | 
| instanceof | 用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上 | var simpleStr = "This is a simple string"; var myString = new String(); console.log(simpleStr instanceof String); // 返回 false,非对象实例,因此返回 false console.log(myString instanceof String); // 返回 true | 
| < | 小于(<)运算符在左操作数比右操作数小时返回 true,否则返回 false | 1 < 2 // true | 
| > | 大于运算符(>)在左操作数大于右操作数时返回 true,否则返回 false | 1 > 2 // false | 
| <= | 小于等于运算符(<=)在左操作数小于等于右操作数时返回 true,否则返回 false | 1 <= 1 // true | 
| >= | 大于等于运算符(>=)在左操作数大于等于右操作数时返回 true,否则返回 false | 2 >= 1 // true | 
相等运算符
如果相等,操作符返回的是布尔类型的 true,否则是 false。
| == | 检查其两个操作数是否相等,只比较值,不比较类型,返回一个布尔值结果,它会比较不同类型的操作数,并尝试强制类型转换 | console.log(1 === '1'); // true console.log(0 === false); // false | 
| != | 检查其两个操作数是否不相等,并返回布尔结果,它会比较不同类型的操作数,并尝试强制类型转换 | console.log(1 != '1'); // false console.log(1 != 2); // true | 
| === | 检查它的两个操作数是否相等,并且返回一个布尔值结果,会比较值和类型 | console.log(1 === '1'); // false console.log(1 === 1); // true | 
| !== | 检查它的两个对象是否不相等,返回一个布尔结果,会判断值和类型 | console.log(1 !== '1'); // true console.log(1 !== 1); // false | 
位移运算符
在二进制的基础上对数字进行移动操作
•按位左移运算符,a << b
左移操作符将第一个操作数向左移动指定位数,左边超出的位数将会被清除,右边将会补零。移动任意数字 x 至左边 y 位,得出 x * 2 ** y。 所以例如:1 << 2 等价于 1 * 22 = 1 * 4 = 4。

•按位右移运算符 a >> b
右移操作符 (>>) 是将一个操作数按指定移动的位数向右移动。 右边移出位将被丢弃,然后用最左边的这一位(符号位)填充左边的空位。 由于新的数字最左边位与之前数字的最左边位是相同值,故符号位(最左边的位)不会改变,因此被称为“符号位传播”(sign-propagating)

•无符号右移 a >>> b
该运算符将第一个操作数向右移动指定的位数。向右移动的多余位将被丢弃。零位从左侧移入。其符号位变为 0,因此其表示的结果始终为非负数。与其他按位运算符不同,零填充右移返回无符号 32 位整数
•>>> 和 >> 的区别
很多同学可能会对>>>和>>的区别很好奇,同样我们来看MDN上对无符号右移>>>的解释:

同样,有一个核心词语:zero-fill right shift。翻译过来就是零-填充,这个就更明显了,右移后空位不管你符号位是什么,我都只填 0。
这里就可以得到一个结论:对于非负数,有符号右移和无符号右移总是返回相同的结果。
二进制运算符
二进制运算符将它们的操作数作为 32 个二进制位(0 或 1)的集合,并返回标准的 JavaScript 数值。
•按位与 &
按位与(&)运算符在两个操作数对应的二进位都为 1 时,该位的结果值才为 1。
| a | b | a AND b | 
| 0 | 0 | 0 | 
| 0 | 1 | 0 | 
| 1 | 0 | 0 | 
| 1 | 1 | 1 | 
•按位或 |
按位或(|)运算符在其中一个或两个操作数对应的二进制位为 1 时,该位的结果值为 1。
| a | b | a OR b | 
| 0 | 0 | 0 | 
| 0 | 1 | 1 | 
| 1 | 0 | 1 | 
| 1 | 1 | 1 | 
•按位异或 ^
按位异或(^)运算符在两个操作数有且仅有一个对应的二进制位为 1 时,该位的结果值为 1。
| a | b | a XOR b | 
| 0 | 0 | 0 | 
| 0 | 1 | 1 | 
| 1 | 0 | 1 | 
| 1 | 1 | 0 | 
二元逻辑运算符
逻辑运算符典型的用法是用于布尔(逻辑)值运算,它们返回布尔值。
| && | 当且仅当所有操作数为 true 时,一组布尔操作数的逻辑与(&&,逻辑连接)运算结果为 true,否则为 false。 | 1 && 2 // true | 
| || | 对于一组操作数的逻辑或(||,逻辑析取)运算符,当且仅当其一个或多个操作数为真,其运算结果为真。 | 1 || 0 // true | 
| ?? | 空值合并运算符,如果 ?? 前面是 null 或 undefined,取后面的默认值 | null ?? 1 // 1 | 
可选链运算符
| ?. | 如果引用是空值(null 或 undefined),可选链运算符将返回 undefined 而不是导致错误。 | var data = { a: 1 }; console.log(data?.b) // undefined | 
三元运算符
| (condition ? ifTrue : ifFalse) | 一个条件后跟一个问号(?),如果条件为真值,则执行冒号(:)前的表达式;若条件为假值,则执行最后的表达式 | const age = 26; const beverage = age >= 21 ? "Beer" : "Juice"; console.log(beverage); // "Beer" | 
赋值运算符
| = | 简单赋值运算符(=)用于给变量赋值 | let x = 2; | 
| *= | 乘法赋值(*=)运算符将变量乘以右操作数的值,并将结果赋值给该变量。 | let bar = 5;bar *= 2; // 10bar *= 'foo'; // NaN | 
| **= | 幂赋值(**=)运算符将左侧变量的值设置为右操作数的幂次方。 | let bar = 5;bar **= 2; // 25bar **= "foo"; // NaN | 
| /= | 除法赋值(/=)运算符将变量除以右操作数的值,并将结果赋值给该变量。 | let bar = 5;bar /= 2; // 2.5bar /= 2; // 1.25bar /= 0; // Infinitybar /= "foo"; // NaN | 
| %= | 取余赋值(%=)运算符将变量除以右操作数的值,并将余数赋值给该变量。 | let bar = 5;bar %= 2; // 1bar %= 'foo'; // NaN | 
| += | 加法赋值运算符(+=)将右操作数的值添加到变量,并将结果分配给该变量。两个操作数的类型决定了加法赋值运算符的行为,可能为加法或拼接。 | let baz = true;// Boolean + Number -> 加法baz += 1; // 2// Number + Boolean -> 加法baz += false; // 2 | 
| -= | 减法赋值(-=)运算符从变量中减去右操作数的值,并将结果赋值给该变量。 | let bar = 5;bar -= 2; // 3bar -= 'foo'; // NaN | 
| <<= | 左移赋值运算符(<<=)将变量向左移动指定的位数,并将结果赋值给变量。 | let a = 5;// 00000000000000000000000000000101a <<= 2; // 20// 00000000000000000000000000010100 | 
| >>= | 右移赋值运算符(>>=)将变量向右移动指定的位数,并将结果赋值给变量。 | let a = 5; //(00000000000000000000000000000101)a >>= 2; // 1 (00000000000000000000000000000001) | 
| >>>= | 无符号右移赋值(>>>=)运算符向右移动移动指定(二进制)位数,并将结果赋值给变量。 | let a = 5; // (00000000000000000000000000000101)a >>>= 2; // 1 (00000000000000000000000000000001) | 
| &= | 按位与赋值运算符(&=)使用两个操作数的二进制表示,对它们进行按位与运算并将结果赋值给变量。 | let a = 5;// 5: 00000000000000000000000000000101// 2: 00000000000000000000000000000010a &= 2; // 0 | 
| ^= | 按位异或赋值操作符 (^=) 使用二进制表示操作数,进行一次按位异或操作并赋值。 | let a = 5; // 00000000000000000000000000000101a ^= 3; // 00000000000000000000000000000011console.log(a); // 00000000000000000000000000000110// 6 | 
| |= | 按位或赋值(|=) 运算符使用两个操作数的二进制表示,对它们执行按位或运算并将结果分配给变量。 | let a = 5;a |= 2; // 7// 5: 00000000000000000000000000000101// 2: 00000000000000000000000000000010// ---------------------------------// 7: 00000000000000000000000000000111 | 
| &&= | 逻辑与赋值(x &&= y)运算仅在 x 为真值时为其赋值。 | let a = 5;a && 2 // 2 | 
| ||= | 逻辑或赋值(x ||= y)运算仅在 x 为假值时为其赋值。 | let a = 1;a || = 3; // 1 | 
| ??= | 逻辑空赋值运算符(x ??= y)仅在 x 是空值(null 或 undefined)时对其赋值。 | let a = null;a ??= 2; // 2 | 
| [a, b] = arr,{ a, b } = obj | 解构赋值语法是一种 Javascript 表达式。可以将数组中的值或对象的属性取出,赋值给其他变量 | let [a, b] = [1, 2];let {c, d} = {c : 1, d: 2} | 
逗号运算符
逗号(,)运算符对它的每个操作数从左到右求值,并返回最后一个操作数的值。这让你可以创建一个复合表达式,其中多个表达式被评估,复合表达式的最终值是其成员表达式中最右边的值。这通常用于为 循环提供多个参数
