JavaScript 操作符

发布于:2025-08-02 ⋅ 阅读:(11) ⋅ 点赞:(0)

JavaScript 操作符

1)一元操作符

只操作一个值的操作符叫一元操作符(unary operator)。

①递增/递减操作符

递增和递减操作符直接照搬自C语言,但有两个版本:前缀版和后缀版。顾名思义,前缀版就是位于要操作的变量前头,后缀版就是位于要操作的变量后头。

前缀递增操作符会给数值加1,把两个加号(++)放到变量前头即可。

前缀递减操作符也类似,只不过是从一个数值减1。只要把两个减号(–)放到变量前头即可。

递增和递减的后缀版语法一样(分别是++和–),只不过要放在变量后面。

后缀版与前缀版的主要区别在于,后缀版递增和递减在语句被求值后才发生。

这4个操作符可以作用于任何值,意思是不限于整数——字符串、布尔值、浮点值,甚至对象都可以。递增和递减操作符遵循如下规则。

  • 对于字符串,如果是有效的数值形式,则转换为数值再应用改变。变量类型从字符串变成数值。
  • 对于字符串,如果不是有效的数值形式,则将变量的值设置为NaN。变量类型从字符串变成数值。
  • 对于布尔值,如果是false,则转换为0再应用改变。变量类型从布尔值变成数值。
  • 对于布尔值,如果是true,则转换为1再应用改变。变量类型从布尔值变成数值。
  • 对于浮点值,加1或减1。
  • 如果是对象,则调用其valueOf()方法取得可以操作的值。对得到的值应用上述规则。如果是NaN,则调用toString()并再次应用其他规则。变量类型从对象变成数值。

②一元加和减

一元加由一个加号(+)表示,放在变量前头,对数值没有任何影响。

如果将一元加应用到非数值,则会执行与使用Number()转型函数一样的类型转换:布尔值false和true转换为0和1,字符串根据特殊规则进行解析,对象会调用它们的valueOf()和/或toString()方法以得到可以转换的值。

一元减由一个减号(-)表示,放在变量前头,主要用于把数值变成负值,如把1转换为-1。

对数值使用一元减会将其变成相应的负值。在应用到非数值时,一元减会遵循与一元加同样的规则,先对它们进行转换,然后再取负值。

2)位操作符

用于数值的底层操作,也就是操作内存中表示数据的比特(位)。

ECMAScript中的所有数值都以IEEE754 64位格式存储,但位操作并不直接应用到64位表示,而是先把值转换为32位整数,再进行位操作,之后再把结果转换为64位。

有符号整数使用32位的前31位表示整数值。第32位表示数值的符号,如0表示正,1表示负。这一位称为符号位(sign bit),它的值决定了数值其余部分的格式。正值以真正的二进制格式存储,即31位中的每一位都代表2的幂。第一位(称为第0位)表示2^0, 第二位表示2^1,依此类推。如果一个位是空的,则以0填充,相当于忽略不计。

负值以一种称为二补数(或补码)的二进制编码存储。一个数值的二补数通过如下3个步骤计算得到:
(1) 确定绝对值的二进制表示(如,对于-18,先确定18的二进制表示);

(2)找到数值的一补数(或反码),换句话说,就是每个0都变成1,每个1都变成0;

(3)给结果加1。

①按位非

按位非操作符用波浪符(~)表示,它的作用是返回数值的一补数。

按位非的最终效果是对数值取反并减1。

②按位与

按位与操作符用和号(&)表示,有两个操作数。本质上,按位与就是将两个数的每一个位对齐,然后基于真值表中的规则,对每一位执行相应的与操作。

按位与操作在两个位都是1时返回1,在任何一位是0时返回0。

③按位或

按位或操作符用管道符(|)表示,同样有两个操作数。按位或遵循如下真值表:

按位或操作在至少一位是1时返回1,两位都是0时返回0。

④按位异或

按位异或用脱字符(^)表示,同样有两个操作数。下面是按位异或的真值表:

按位异或与按位或的区别是,它只在一位上是1的时候返回1(两位都是1或0,则返回0)。

⑤左移

左移操作符用两个小于号(<<)表示,会按照指定的位数将数值的所有位向左移动。

注意在移位后,数值右端会空出5位。左移会以0填充这些空位,让结果是完整的32位数值。

注意,左移会保留它所操作数值的符号。比如,如果-2左移5位,将得到-64,而不是正64。

⑥有符号右移

有符号右移由两个大于号(>>)表示,会将数值的所有32位都向右移,同时保留符号(正或负)。有符号右移实际上是左移的逆运算。比如,如果将64右移5位,那就是2。

同样,移位后就会出现空位。不过,右移后空位会出现在左侧,且在符号位之后。

ECMAScript会用符号位的值来填充这些空位,以得到完整的数值。

⑦无符号右移

无符号右移用3个大于号表示(>>>),会将数值的所有32位都向右移。

对于正数,无符号右移与有符号右移结果相同。

对于负数,有时候差异会非常大。与有符号右移不同,无符号右移会给空位补0,而不管符号位是什么。对正数来说,这跟有符号右移效果相同。但对负数来说,结果就差太多了。无符号右移操作符将负数的二进制表示当成正数的二进制表示来处理。因为负数是其绝对值的二补数,所以右移之后结果变得非常之大。

3)布尔操作符

①逻辑非

逻辑非操作符由一个叹号(!)表示,可应用给ECMAScript中的任何值。这个操作符始终返回布尔值,无论应用到的是什么数据类型。逻辑非操作符首先将操作数转换为布尔值,然后再对其取反。换句话说,逻辑非操作符会遵循如下规则。

  • 如果操作数是对象,则返回false。
  • 如果操作数是空字符串,则返回true。
  • 如果操作数是非空字符串,则返回false。
  • 如果操作数是数值0,则返回true。
  • 如果操作数是非0数值(包括Infinity),则返回false。
  • 如果操作数是null,则返回true。
  • 如果操作数是NaN,则返回true。
  • 如果操作数是undefined,则返回true。

逻辑非操作符也可以用于把任意值转换为布尔值。同时使用两个叹号(! !),相当于调用了转型函数Boolean()。无论操作数是什么类型,第一个叹号总会返回布尔值。第二个叹号对该布尔值取反,从而给出变量真正对应的布尔值。结果与对同一个值使用Boolean()函数是一样的。

②逻辑与

逻辑与操作符由两个和号(&&)表示,应用到两个值。

逻辑与操作符遵循如下真值表:

逻辑与操作符可用于任何类型的操作数,不限于布尔值。如果有操作数不是布尔值,则逻辑与并不一定会返回布尔值,而是遵循如下规则。

  • 如果第一个操作数是对象,则返回第二个操作数。
  • 如果第二个操作数是对象,则只有第一个操作数求值为true才会返回该对象。
  • 如果两个操作数都是对象,则返回第二个操作数。
  • 如果有一个操作数是null,则返回null。
  • 如果有一个操作数是NaN,则返回NaN。
  • 如果有一个操作数是undefined,则返回undefined。

逻辑与操作符是一种短路操作符,意思就是如果第一个操作数决定了结果,那么永远不会对第二个操作数求值。对逻辑与操作符来说,如果第一个操作数是false,那么无论第二个操作数是什么值,结果也不可能等于true。

③逻辑或

逻辑或操作符由两个管道符(||)表示。

逻辑或操作符遵循如下真值表:

与逻辑与类似,如果有一个操作数不是布尔值,那么逻辑或操作符也不一定返回布尔值。它遵循如下规则。

  • 如果第一个操作数是对象,则返回第一个操作数。
  • 如果第一个操作数求值为false,则返回第二个操作数。
  • 如果两个操作数都是对象,则返回第一个操作数。
  • 如果两个操作数都是null,则返回null。
  • 如果两个操作数都是NaN,则返回NaN。
  • 如果两个操作数都是undefined,则返回undefined。

同样与逻辑与类似,逻辑或操作符也具有短路的特性。只不过对逻辑或而言,第一个操作数求值为true,第二个操作数就不会再被求值了。

4)乘性操作符

ECMAScript定义了3个乘性操作符:乘法、除法和取模。
如果乘性操作符有不是数值的操作数,则该操作数会在后台被使用Number()转型函数转换为数值。这意味着空字符串会被当成0,而布尔值true会被当成1。

①乘法操作符

乘法操作符由一个星号(*)表示,可以用于计算两个数值的乘积。

不过,乘法操作符在处理特殊值时也有一些特殊的行为。

  • 如果操作数都是数值,则执行常规的乘法运算,即两个正值相乘是正值,两个负值相乘也是正值,正负符号不同的值相乘得到负值。如果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或-Infinity。
  • 如果有不是数值的操作数,则先在后台用Number()函数将其转换为数值,然后再应用上述规则。

③取模操作符

取模(余数)操作符由一个百分比符号(%)表示。

与其他乘性操作符一样,取模操作符对特殊值也有一些特殊的行为。

  • 如果操作数是数值,则执行常规除法运算,返回余数。
  • 如果被除数是无限值,除数是有限值,则返回NaN。
  • 如果被除数是有限值,除数是0,则返回NaN。
  • 如果是Infinity除以Infinity,则返回NaN。
  • 如果被除数是有限值,除数是无限值,则返回被除数。
  • 如果被除数是0,除数不是0,则返回0。
  • 如果有不是数值的操作数,则先在后台用Number()函数将其转换为数值,然后再应用上述规则。

5)指数操作符

ECMAScript 7新增了指数操作符,Math.pow()现在有了自己的操作符**,结果是一样的。
指数操作符也有自己的指数赋值操作符**=,该操作符执行指数运算和结果的赋值操作。

6)加性操作符
加性操作符,即加法和减法操作符,一般都是编程语言中最简单的操作符。不过,在ECMAScript中,这两个操作符拥有一些特殊的行为。

①加法操作符

加法操作符(+)用于求两个数的和。

如果两个操作数都是数值,加法操作符执行加法运算并根据如下规则返回结果:

  • 如果有任一操作数是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"。

②减法操作符

减法操作符(-)也是使用很频繁的一种操作符。

与加法操作符一样,减法操作符也有一组规则用于处理ECMAScript中不同类型之间的转换。

  • 如果两个操作数都是数值,则执行数学减法运算并返回结果。
  • 如果有任一操作数是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()方法,然后再将得到的字符串转换为数值。

7)关系操作符

关系操作符执行比较两个值的操作,包括小于(<)、大于(>)、小于等于(<=)和大于等于(>=),用法跟数学课上学的一样。这几个操作符都返回布尔值。

与ECMAScript中的其他操作符一样,在将它们应用到不同数据类型时也会发生类型转换和其他行为。

  • 如果操作数都是数值,则执行数值比较。
  • 如果操作数都是字符串,则逐个比较字符串中对应字符的编码。
  • 如果有任一操作数是数值,则将另一个操作数转换为数值,执行数值比较。
  • 如果有任一操作数是对象,则调用其valueOf()方法,取得结果后再根据前面的规则执行比较。如果没有valueOf()操作符,则调用toString()方法,取得结果后再根据前面的规则执行比较。
  • 如果有任一操作数是布尔值,则将其转换为数值再执行比较。

对字符串而言,关系操作符会比较字符串中对应字符的编码,而这些编码是数值。比较完之后,会返回布尔值。大写字母的编码都小于小写字母的编码。

任何关系操作符在涉及比较NaN时都返回false。

8)相等操作符

ECMAScript提供了两组操作符。第一组是等于和不等于,它们在比较之前执行转换。第二组是全等和不全等,它们在比较之前不执行转换。

①等于和不等于

ECMAScript中的等于操作符用两个等于号(==)表示,如果操作数相等,则会返回true。

不等于操作符用叹号和等于号(! =)表示,如果两个操作数不相等,则会返回true。

这两个操作符都会先进行类型转换(通常称为强制类型转换)再确定操作数是否相等。

在转换操作数的类型时,相等和不相等操作符遵循如下规则。

  • 如果任一操作数是布尔值,则将其转换为数值再比较是否相等。false转换为0, true转换为1。
  • 如果一个操作数是字符串,另一个操作数是数值,则尝试将字符串转换为数值,再比较是否相等。
  • 如果一个操作数是对象,另一个操作数不是,则调用对象的valueOf()方法取得其原始值,再根据前面的规则进行比较。

在进行比较时,这两个操作符会遵循如下规则。

  • null和undefined相等。
  • null和undefined不能转换为其他类型的值再进行比较。
  • 如果有任一操作数是NaN,则相等操作符返回false,不相等操作符返回true。记住:即使两个操作数都是NaN,相等操作符也返回false,因为按照规则,NaN不等于NaN。
  • 如果两个操作数都是对象,则比较它们是不是同一个对象。如果两个操作数都指向同一个对象,则相等操作符返回true。否则,两者不相等。

②全等和不全等

全等和不全等操作符与相等和不相等操作符类似,只不过它们在比较相等时不转换操作数。

全等操作符由3个等于号(===)表示,只有两个操作数在不转换的前提下相等才返回true。

不全等操作符用一个叹号和两个等于号(! ==)表示,只有两个操作数在不转换的前提下不相等才返回true。

虽然null == undefined是true(因为这两个值类似),但null === undefined是false,因为它们不是相同的数据类型。

注意 由于相等和不相等操作符存在类型转换问题,因此推荐使用全等和不全等操作符。这样有助于在代码中保持数据类型的完整性。

9)条件操作符

variable = boolean_expression ? true_value : false_value;

上面的代码执行了条件赋值操作,即根据条件表达式boolean_expression的值决定将哪个值赋给变量variable。如果boolean_expression是true,则赋值true_value;如果boolean_expression是false,则赋值false_value。

10)赋值操作符

简单赋值用等于号(=)表示,将右手边的值赋给左手边的变量。

复合赋值使用乘性、加性或位操作符后跟等于号(=)表示。

每个数学操作符以及其他一些操作符都有对应的复合赋值操作符:

  • 乘后赋值(*=)
  • 除后赋值(/=)
  • 取模后赋值(%=)
  • 加后赋值(+=)
  • 减后赋值(-=)
  • 左移后赋值(<<=)
  • 右移后赋值(>>=)
  • 无符号右移后赋值(>>>=)

11)逗号操作符

逗号操作符可以用来在一条语句中执行多个操作,如下所示:

let num1 = 1, num2 = 2, num3 = 3;

在一条语句中同时声明多个变量是逗号操作符最常用的场景。不过,也可以使用逗号操作符来辅助赋值。在赋值时使用逗号操作符分隔值,最终会返回表达式中最后一个值:

let num = (5, 1, 4, 8, 0); // num的值为0

在这个例子中,num将被赋值为0,因为0是表达式中最后一项。逗号操作符的这种使用场景并不多见,但这种行为的确存在。


网站公告

今日签到

点亮在社区的每一天
去签到