- 操作符
- ES描述了一组可用于操作数据值的操作符
- 数学操作符
- 位操作符
- 关系操作符
- 相等操作符
- ES中的操作符是独特的,因为它们可用于各种值(包括字符串、数值、布尔值、对象)。
- 操作符通常会调用valueOf()和/或toString()方法来取得计算的值。
- ES描述了一组可用于操作数据值的操作符
一元操作符
-
只操作一个值的操作符叫一元操作符。ES中最简单的操作符。
-
++/–操作符
- 递增和递减操作符直接照搬自C语言,前缀版和后缀版
let age = 29;
++age;
// 实际上等于如下表达式
let age = 29;
age = age + 1;
--age;
// 等同于
age = age - 1;
- 无论使用前缀递增还是前缀递减操作符,变量的值都会在语句被求值之前改变。(在计算机科学中,这被称为具有
副作用
)
let age = 29;
let antherAge = --age + 2; // = (age - 1) + 2
age // 28;由于具有副作用,age - 1
antherAge // 30
let num1 = 2;
let num2 = 20;
let num3 = --num1 + num2; // = (num1 - 1) + 2 => 21
let num4 = num1 + num2; // 1 + 20 => 21
- 后缀版本:
- 和前缀版的主要区别在于,后缀版递增和递减在语句被求值后才发生。某些情况下,这种差异没什么影响。
let num1 = 2;
let num2 = 20;
let num3 = num1-- + num2; // 2 + 20 => 22,计算完num1 + num2之后,才执行num1 - 1
let num4 = num1 + num2; // 1 + 20 => 21
-
这 4个操作符可以作用于任何值,意思是不限于整数——字符串、布尔值、浮点值,甚至对象都可以.
-
递增和递减操作符遵循如下规则:
- 对于字符串,若为有效数值形式,则转换为数值再应用改变。变量类型从字符串变成数值。
- 对于字符串,若不是有效的数值形式,则讲变量的值设置为NaN。变量类型从字符串变成数值。
- 布尔值,false => 0; true => 1。
- 浮点值,加1或减1
- 对象,调用valueOf()方法取得可以操作的值。对得到的值应用上述规则。如果是NaN,则调用toString()并再次应用其他规则。变量类型从对象变成数值。
let s1 = "2"; // s1++ => 3 let s2 = "z"; // s2++ => NaN let b = false; // b++ => 1 let f = 1.1; // f++ => 2.1; f-- => 值变成 0.10000000000000009(因为浮点数不精确) let o = { valueOf() { return -1; } }; // o-- => -2
-
一元加和减
- 一元加和减操作符对于大多数开发者来说并不陌生。
- 如果将一元加,减应用到非数值,则会执行与使用Number()转型函数一样的类型转换:
- false: 0; true: 1;
- 字符串根据特殊规则进行解析,对象会调用它们的valueOf()和/或toString()方法以得到可以转换的值。
-
位操作符
- 操作内存中表示数据的比特(位)。
- ES中所有数值都以IEEE 754 64位格式存储,但位操作符并不直接应用到64位表示,而是先把值转换成32位整数,再进行位操作,之后再把结果转换为64位。
- 对于开发者而言,只需要考虑32位整数即可。64位整数存储格式是不可见的。
- 有符号整数使用32位的前31位表示整数值,第32位表示符号,0正;1负
- 正值以真正的二进制格式存储。
- 负值以补码的形式存储。
- 补码的计算步骤:
- 1.确定绝对值的二进制表示(如,对于-18,先确定18的二进制表示);
- 2.找到数值的反码(每个0变成1,1变成0);
- 3.给结果加1。
let num = -18; console.log(num.toString(2)); // "-10010"
- 默认情况下,ES中所有整数都表示为有符号数。不过确实存在无符号整数。对无符号整数来说,第 32 位不表示符号,因为只有正值。无符号整数比有符号整数的范围更大,因为符号位被用来表示数值了。
- 在对 ECMAScript 中的数值应用位操作符时,后台会发生转换:64 位数值会转换为 32 位数值,然后执行位操作,最后再把结果从 32 位转换为 64 位存储起来。整个过程就像处理32位数值一样,就让二进制操作变得和其他语言类似。
- 这个转换导致一个奇特的副作用,就是特殊值NaN和Infinity在位操作中都会被当成0处理。
- 若将位操作符应用到非数值,那么首先会使用Number()函数转换位数值,然后在应用位操作。最终结果是数值。
-
按位非
- ~
- 作用:返回数值反码
-
按位与
- &
- 有2个操作数,本质上,按位与就是将两个数的每一位对齐。
第一个数值的位 第二个数值的位 结果 1 1 1 1 0 0 0 1 0 0 0 0 let result = 25 & 3 result // 1
-
按位或
- |
- 2个操作数
第一个数值的位 第二个数值的位 结果 1 1 1 1 0 1 0 1 1 0 0 0 - 至少的有一个1。
let result = 25 | 3; result // 27
-
按位异或
- ^
- 有2个操作数
第一个数值的位 第二个数值的位 结果 1 1 0 1 0 1 0 1 1 0 0 0 - 按位异或与按位或的区别就是,它只在一位上是1时,返回1(两位都是1,或0,则返回0)
let result = 25 ^ 3; result // 26
-
左移
<<
- 左移会以0填充空出来的位置
-
有符号右移
>>
- 会将数值的所有32位都向右移动,同时保留符号。有符号右移其实时左移的逆运算。
-
无符号右移
>>>
- 会将数值的所有32位都向右移。
- 对于正数,无符号右移与有符号右移结果相同。
- 对于负数,无符号右移操作符将负数的二进制表示当成正数的二进制表示来处理。因为负数是其绝对值的二补数,所以右移之后结果变得非常之大。
-
布尔操作符
- 逻辑非
- 逻辑与
- 逻辑或
-
逻辑非
!
- 取反
- 逻辑非操作符遵循规则:
- 操作数是对象,返回 false;
- 是空字符串, 返回 true;
- 是非空字符串, 返回 false;
- 是数值0, 返回 true;
- 是非0数值(包括Infinity),返回 false
- 是null, 返回 true
- 是 NaN, 返回 true;
- 是undefined, 返回 true
-
同时使用两个叹号(!!),相当于调用了转型函数Boolean()
。无论操作数是什么类型,第一个叹号总会返回布尔值。第二个叹号对该布尔值取反,从而给出变量真正对应的布尔值。结果与对同一个值使用Boolean()是一样的:
console.log(!false); // true
console.log(!"blue"); // false
console.log(!0); // true
console.log(!NaN); // true
console.log(!""); // true
console.log(!12345); // false
!!"blue" // true
!!0 // false
!!NaN // false
!!"" // false
!!12345 // true
-
逻辑与
-
&&
-
都真才真
-
逻辑与操作符可用于任何类型的操作数,不限于布尔值。如果有操作数不是布尔值,则逻辑与并不一定返回布尔值,而是遵循如下规则:
第一个操作数 第二个操作数 结果 Object any 返回第二个操作符 求值为true Object 返回第一个操作符 Object Object 返回第二个操作符 null any 返回null NaN any 返回NaN undefined any 返回undefined -
逻辑与操作符是一种短路操作符,意思就是如果第一个操作数决定了结果,那么永远不会对第二个操作数求值。对逻辑与操作符来说,如果第一个操作数是 false,那么无论第二个操作数是什么值,结果也不可能等于 true。
-
-
逻辑或
-
||
-
有一个真就真
-
逻辑或操作符遵循的规则:
第一个操作符 第二个操作符 结果 Object any 返回第一个操作符 Object Object 返回第一个操作符 求值为false any 返回第二个操作符 null null 返回null NaN NaN 返回NaN undefined undefined 返回undefined -
同样与逻辑与类似,逻辑或操作符也具有短路的特性。只不过对逻辑或而言,第一个操作数求值为
true,第二个操作数就不会再被求值了。
-
-
乘性操作符
- 乘法
- 除法
- 取模
-
这些操作符跟它们在Java、C语言中的作用一样。
-
乘法操作符
-
-
除法操作符
- /
-
取模操作符
- %
-
指数操作符
- Math.pow(3, 2)
- 3 ** 2
-
加性操作符
-
-
关系操作符
<
>
<=
>=
-
相等操作符
- 等于 ==
- 不等于 !=
- 全等 ===
- 不全等 !==
-
条件操作符
? :
-
赋值操作符
=
- 乘后赋值(*=)
- 除后赋值(/=)
- 取模后赋值(%=)
- 加后赋值(+=)
- 减后赋值(-=)
- 左移后赋值(<<=)
- 右移后赋值(>>=)
- 无符号右移后赋值(>>>=)
-
逗号操作符
- ,