操作符包括:数学操作符、位操作符、关系操作符和相等操作符。
操作符可用于各种值,包括字符串、数值、布尔值、甚至还有对象。
在应用给对象时,操作符通常会调用 valueOf()和/或 toString()方法来取得可以计算的值。
一元操作符 定义
递增/递减操作符 分类
前缀版
操作符位于待操作变量的前面
副作用:无论使用前缀递增还是前缀递减操作符,变量的值都会在语句被求值之前改变1 2 3 4 5 6 let num = 10 ;let other = --num + 5 ;let another = num + 5 ;console .log (num);console .log (other);console .log (another);
后缀版
操作符位于待操作变量的后面
后缀版递增和递减在语句被求值后才发生1 2 3 4 let num = 10 ;let another = num-- + 5 ;console .log (num);console .log (another);
前缀递增和递减在语句中的优先级是相等的,因此会从左到右依次求值。
规则
数据类型
规则
类型转换
字符串
有效数值形式,转换为数值再应用改变
字符串→数值
字符串
非有效数值形式,将变量的值设置为NaN
字符串→数值
true
转换为1再应用改变
布尔值→数值
false
转换为0再应用改变
布尔值→数值
浮点数
加1或减1
对象
调用valueOf()方法取得可以操作的值,对得到的值应用上述规则;如果是NaN,则调用toString()并再次应用其他规则
对象→数值
一元加和减 一元加号
如果将一元加应用到非数值,则会执行与使用 Number()转型函数一样的类型转换;
布尔值 false和 true 转换为 0 和 1;
字符串根据特殊规则进行解析;
对象会调用它们的 valueOf()和/或 toString()方法以得到可以转换的值。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 let s1 = "01" ;let s2 = "1.1" ;let s3 = "z" ;let a = '25' ;let b = false ;let f = 1.1 ;let o = { valueOf ( ){ return -1 ; } } console .log (+s1);console .log (+s2);console .log (+s3);console .log (+a);console .log (+b);console .log (+f);console .log (+o);
一元减号
一元减由一个减号(-)表示,放在变量前头,主要用于把数值变成负值;
在应用到非数值时,一元减会遵循与一元加同样的规则,先对它们进行转换,然后再取负值:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 let s1 = "01" ;let s2 = "1.1" ;let s3 = "z" ;let a = '25' ;let b = false ;let f = 1.1 ;let o = { valueOf ( ){ return -1 ; } } console .log (-s1);console .log (-s2);console .log (-s3);console .log (-a);console .log (-b);console .log (-f);console .log (-o);
位操作符
ECMAScript中的所有数值都以 IEEE 754 64位格式存储;
位操作并不直接应用到 64 位表示,而是先把值转换为32位整数,再进行位操作,之后再把结果转换为64位;
有符号整数使用 32 位的前 31 位表示整数值;第 32 位表示数值的符号,如 0 表示正,1 表示负。
负值以一种称为二补数(或补码)的二进制编码存储。
特殊值NaN 和Infinity在位操作中都会被当成 0 处理;
如果将位操作符应用到非数值,那么首先会使用 Number()函数将该值转换为数值(这个过程是自动的),然后再应用位操作。最终结果是数值。
按位非
按位非操作符用波浪符(~)表示
按位非的最终效果是对数值取反并减 1
按位与
a
b
result
1
1
1
1
0
0
0
1
0
0
0
0
按位或
a
b
result
1
1
1
1
0
1
0
1
1
0
0
0
按位异或
按位异或操作符用脱字符(^)表示。
真值表:a^b
a
b
result
1
1
0
1
0
1
0
1
1
0
0
0
左移
左移操作符用两个小于号(<<)表示
如果数值 2(二进制 10)向左移 5 位,就会得到 64(二进制 1000000)
有符号右移
有符号右移由两个大于号(>>)表示,会将数值的所有 32 位都向右移,同时保留符号(正或负)
无符号右移
无符号移用 3 个大于号表示(>>>),会将数值的所有 32 位都向右移
对于正数,无符号右移与有符号右移结果相同。
布尔操作符 布尔操作符一共有 3 个:逻辑非、逻辑与和逻辑或。
逻辑非
逻辑非操作符由一个叹号(!)表示,可应用给 ECMAScript 中的任何值,始终返回布尔值。
逻辑非操作符首先将操作数转换为布尔值,然后再对其取反。
转化规则:
操作数
结果
对象
false
空字符串
true
非空字符串
false
数值0
true
非0数值
false
null
true
NaN
true
underfined
true
同时使用两个叹号(!!),相当于调用了转型函数 Boolean()。
逻辑与
操作数一
操作数二
result
true
true
true
true
false
false
false
true
false
false
false
false
如果有操作数不是布尔值,则逻辑与并不一定会返回布尔值,而是遵循如下规则:
操作数
结果
第一个操作数是对象
返回第二个操作数
第二个操作数是对象
只有第一个操作数求值为true才会返回该对象
两个操作数都是对象
返回第二个操作数
有一个操作数是null
返回null
有一个操作数是NaN
返回NaN
有一个操作数是underfined
返回underfinded
逻辑与操作符是一种短路操作符,意思就是如果第一个操作数决定了结果,那么永远不会对第二个操作数求值。
当变量未被定义则不能对它应用逻辑与操作符。
逻辑或
操作数一
操作数二
result
true
true
true
true
false
true
false
true
true
false
false
false
如果有操作数不是布尔值,则逻辑与并不一定会返回布尔值,而是遵循如下规则:
操作数
结果
第一个操作数是对象
返回第一个操作数
第二个操作数求值为false
返回第二个操作数
两个操作数都是对象
返回第一个操作数
两个操作数是null
返回null
两个操作数是NaN
返回NaN
两个操作数是underfined
返回underfinded
逻辑或操作符也具有短路的特性,第一个操作数求值为true,第二个操作数就不会再被求值了。
乘性操作符
ECMAScript 定义了 3 个乘性操作符:乘法、除法和取模 。
如果乘性操作符有不是数值的操作数,则该操作数会在后台被使用 Number()转型函数转换为数值。
乘法操作符(*)
操作数
结果
都是数值
正值相乘为正,负值相乘为正,正负不同相乘为负;如果 ECMAScript 不能表示乘积,则返回 Infinity 或-Infinity。
如果有任一操作数是 NaN
返回 NaN
如果是 Infinity乘以 0
返回 NaN
如果是 Infinity 乘以非 0的有限数值
根据第二个操作数的符号返回 Infinity 或-Infinity
如果是 Infinity 乘以 Infinity
返回 Infinity
如果有不是数值的操作数
先在后台用 Number()将其转换为数值,然后再应用上述规则
除法操作符(/)
操作数
结果
都是数值
正值相乘为正,负值相除为正,正负不同相除为负;如果 ECMAScript 不能表示商,则返回 Infinity 或-Infinity。
如果有任一操作数是 NaN
返回 NaN
如果是 Infinity除以 Infinity
返回 NaN
如果是 0除以 0
返回 NaN
如果是 非0的有限值除以0
根据第一个操作数的符号返回 Infinity 或-Infinity
如果是 Infinity 除以任何数值
根据第二个操作数的符号返回 Infinity
如果有不是数值的操作数
先在后台用 Number()将其转换为数值,然后再应用上述规则
取模操作数(%)
操作数
结果
都是数值
执行常规除法运算,返回余数
如果被除数是无限值,除数是有限值
返回 NaN
如果被除数是有限值,除数是0
返回 NaN
如果是 0 除以 0
返回 NaN
如果是 Infinity 除以 Infinity
返回NaN
如果被除数是有限值,除数是无限值
返回NaN
如果被除数是 0 ,除数不是 0
返回0
如果有不是数值的操作数
先在后台用 Number()将其转换为数值,然后再应用上述规则
指数操作数
ES7新增了指数操作符“**”等价于Math.pow()
指数操作符也有指数赋值操作符**=
加性操作符 加法操作符
操作数
结果
如果有任一操作数是 NaN
返回 NaN
如果是 Infinity 加 Infinity
返回 Infinity
如果是 -Infinity 加 -Infinity
返回 -Infinity
如果是 Infinity 加 -Infinity
返回 NaN
如果是 +0 加 +0
返回 +0
如果是 -0 加 +0
返回 +0
如果是 -0 加 -0
返回 -0
操作数
结果
如果两个操作数都是字符串
第二个字符串拼接到第一个字符串后面
如果只有一个操作数是字符串
将另一个操作数转为字符串,然后再将两个字符串拼接在一起
如果有任一操作数是对象、数值或布尔值,则调用它们的 toString()方法以获取字符串,然后再应用前面的关于字符串的规则。
对于 undefined 和 null,则调用 String()函数,分别获取”undefined”和”null”。
减法操作符
操作数
结果
如果有任一操作数是 NaN
返回 NaN
如果是 Infinity 减 Infinity
返回 NaN
如果是 -Infinity 减 -Infinity
返回 NaN
如果是 Infinity 减 -Infinity
返回 Infinity
如果是 -Infinity 减 Infinity
返回 -Infinity
如果是 +0 加 +0
返回 +0
如果是 +0 加 -0
返回 -0
如果是 -0 加 -0
返回 +0
如果有任一操作数是字符串、布尔值、null 或 undefined,则先在后台使用 Number()将其转换为数值,然后再根据前面的规则执行数学运算。如果转换结果是 NaN,则减法计算的结果是NaN。
如果有任一操作数是对象,则调用其 valueOf()方法取得表示它的数值。如果该值是 NaN,则减法计算的结果是 NaN。如果对象没有 valueOf()方法,则调用其 toString()方法,然后再将得到的字符串转换为数值。
关系操作符
关系操作符执行比较两个值的操作,包括小于(<)、大于(>)、小于等于(<=)和大于等于(>=)。
操作数
结果
都是数值
执行数值比较
都是字符串
比较字符串中对应字符的编码
如果有任一操作数是数值
将另一个操作数转换为数值,执行数值比较
如果有任一操作数是对象
调用其valueOf()方法,取得结果后再根据前面的规则执行比较;如果对象没有 valueOf()方法,则调用其 toString()方法,取得结果后再根据前面的规则执行比较
如果有任一操作数是布尔值
将其转换为数值再执行比较
相等操作符 等于和不等于
等于操作符用两个等于号(==)表示
不等于操作符用叹号和等于号(!=)表示
这两个操作符都会先进行类型转换(通常称为强制类型转换)再确定操作数是否相等。
转换规则如下:
操作数
结果
如果有任一操作数是布尔值
将其转换为数值再比较是否相等
如果一个操作数是字符串,另一个操作数是数值
࠼试将字符串转换为数值,再比较是否相等
如果一个操作数是对象,另一个操作数不是
调用对象的 valueOf()方法取得其原始值,再根据前面的规则进行比较
在进行比较时,这两个操作符会遵循以下规则:
null和underfined相等
null 和 undefined 不能转换为其他类型的值再进行比较
如果有任一操作数是 NaN,则相等操作符返回 false,不相等操作符返回 true
如果两个操作数都是对象,则比较它们是不是同一个对象
全等和不全等
全等操作符由 3 个等于号(===)表示,只有两个操作数在不转换的前提下相等才返回回 true
条件操作符 variable = boolean_expression ? true_value : false_value
赋值操作符
简单赋值用等于号(=)表示,将左手边的值赋给右手边的变量
复合赋值:仅仅是简写语法,使用它们不会提升性能
逗号操作符
逗号操作符可以用来在一条语句中执行多个操作
在赋值时使用逗号操作符分隔值,最终会返回表达式中最后一个值1 2 let num = (5 ,1 ,4 ,8 ,0 );console .log (num);