本章描述了 JavaScript 的表达式和运算符,包括了赋值,比较,算数,位运算,逻辑,字符串,三元等等。
JavaScript 拥有如下类型的运算符。本节描述了运算符和运算符的优先级。
JavaScript 拥有二元和一元运算符,和一个特殊的三元运算符(条件运算符)。一个二元运算符需要两个操作数,分别在运算符的前面和后面:
操作数 1 运算符 操作数 2
例如,3+4 或 x*y。
一个一元运算符需要一个操作数,在运算符前面或后面:
运算符 操作数
或者
操作数 运算符
例如,x++ 或 ++x。
一个 赋值运算符 (assignment operator) (en-US) 将它右边操作数的值赋给它左边的操作数。最简单的赋值运算符是等于(=),它将右边的操作数值赋给左边的操作数。那么 x = y 就是将 y 的值赋给 x。
还有一些复合赋值操作符,它们是下表列出的这些操作的缩写:
名字 | 简写的操作符 | 含义 |
---|---|---|
赋值 (Assignment) (en-US) | x = y | x = y |
加法赋值 (Addition assignment) (en-US) | x += y | x = x + y |
减法赋值 (Subtraction assignment) (en-US) | x -= y | x = x - y |
乘法赋值 (Multiplication assignment) (en-US) | x *= y | x = x * y |
除法赋值 (Division assignment) (en-US) | x /= y | x = x / y |
求余赋值 (Remainder assignment) (en-US) | x %= y | x = x % y |
求幂赋值 (Exponentiation assignment) (en-US) | x **= y | x = x ** y |
左移位赋值 (Left shift assignment) (en-US) | x <<= y | x = x << y |
右移位赋值 (Right shift assignment) (en-US) | x >>= y | x = x >> y |
无符号右移位赋值 (Unsigned right shift assignment) (en-US) | x >>>= y | x = x >>> y |
按位与赋值 (Bitwise AND assignment) (en-US) | x &= y | x = x & y |
按位异或赋值 (Bitwise XOR assignment) (en-US) | x ^= y | x = x ^ y |
按位或赋值 (Bitwise OR assignment) (en-US) | x | = y |
对于更复杂的赋值,解构赋值语法是一个能从数组或对象对应的数组结构或对象字面量里提取数据的 Javascript 表达式。
var foo = ["one", "two", "three"];
// 不使用解构
var one = foo[0];
var two = foo[1];
var three = foo[2];
// 使用解构
var [one, two, three] = foo;
读取对象属性的时候,如果某个属性的值是 null 或 undefined,有时候需要为它们指定默认值。常见做法是通过 || 运算符指定默认值。
const text = data.text || 'Hello, world!'
上面的代码都通过 || 运算符指定默认值,但是这样写可能和预期的结果不一致。
开发者的原意是,只要属性的值为 null 或 undefined,默认值就会生效,但是属性的值如果为空字符串或 false 或 0,默认值也会生效。
为了避免这种情况,ES2020 引入了一个新的 Null 判断运算符??。它的行为类似 ||,但是只有运算符左侧的值为 null 或 undefined 时,才会返回右侧的值。
const text = data.text ?? 'Hello, world!'
上面代码中,默认值只有在属性值为 null 或 undefined 时,才会生效。
这个运算符的一个目的,就是跟链判断运算符 ?. 配合使用,为 null 或 undefined 的值设置默认值。
const animationDuration = settings?.animationDuration ?? 300
上面代码中,settings 如果是 null 或 undefined,就会返回默认值300。
并没有专用的字符串运算符,只是有些运算符在遇到字符串运算数的时候,表现不同。
(I)“+”连接2个字符串;
1)当2个运算数都是字符串的时候,连接起来;
2)当其中有一个是数字的时候,将数字转换成字符串,连接起来;
(II)“>”这样的比较运算符通过比较确认两个字符串的顺序,比较采用字符的顺序,较小的位于教大的前面,大写字母位于小写字母之前。
(III)“+”的作用方法取决于计算顺序,
如:s = 1 + 2 +“var” 则:返回结果3var; 因为先计算1+2,然后将结果3转换成字符串与"var"连接;
如:s = “var” + 1 + 2 则:返回结果var12; 因为先计算var与1的连接,在将结果var1与转换成字符串的2连接起来。
(I)“=”是赋值运算符;他总是期望左边的运算数是一个变量、数组的一个元素或对象的一个属性;
期望右边是一个任意类型的任意的值;
从右到左的结合性,如果一个表达式中有多个赋值运算符,则从最右边开始计算。
注意:每一个赋值表达式都有一个值,就是运算符右边的值;
(II)可以使用带操作的赋值运算
“+=” 左边的值加上右边的值后,赋值于左边的值。“-=”“/=”“*=”方法一样;
现代计算机中数据都是以二进制的形式存储的,即0、1两种状态,计算机对二进制数据进行的运算加减乘除等都是叫位运算,即将符号位共同参与运算的运算。
JavaScript中所有的数字都是以IEEE 754 64位格式存储,但是位操作并不直接应用到64位,而是先将值转化为32位整数,再进行位操作。之后再把运算结果转化为64位,所以我们只需要考虑32位整数即可。位操作是在数值的底层完成的,所以运算速度会相对于其他运算符快很多。
常见的位运算有以下几种:
在说这些操作符之前,先来看几个相关的概念。计算机中的有符号数有三种表示方法,即原码、反码和补码。三种表示方法均有符号位和数值位两部分,符号位都是用0表示“正”,用1表示“负”,而数值位,三种表示方法各不相同。
(1)原码
原码就是一个数的二进制数。例如:10的原码为0000 1010
(2)反码
例如,-10的反码如下:
原码:1000 1010
反码:1111 0101
(3)补码
例如,-10的补码如下:
原码:1000 1010
反码:1111 0101
补码:1111 0110