ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
[TOC] >>[info] 操作符按使用方法可以分为:一元操作符、位操作符、布尔操作符、乘性操作符、加性操作符、关系操作符、相等操作符、条件操作符、赋值操作符、逗号操作符这10种操作符。ECMAScript 操作符的与众不同之处在于,它们能够适用于很多值,例如字符串、数字值、布尔值,甚至对象。不过,在应用于对象时,相应的操作符通常都会调用对象的 valueOf()和(或) toString()方法,以便取得可以操作的值。 ## 一元操作符 只能操作一个值的操作符,叫**一元操作符**。一元运算符是ECMAScript中最简单的操作符。 #### 1、递增和递减操作符 递增递减即`++`和`--`,而递增和递减又分为前置型(前`++`或前`--`)和后置型(后`++`或后`--`),前置型为先递增或递减,而后置型为下次使用时再进行递增或递减。 ~~~ var age = 20; alert(++age); // 21,前置型,这里相当于 age + 1 var age = 20; alert(age--); // 20,后置型,先使用,后递减,所以这里得到的值依然是20 alert(age); // 19,此时再使用到此变量时,会进行前面的递减操作,所以得到的是 19 var age = 20; var newAge = --age + 2; alert(age); // 19,因为 age 在上一行被执行了前置递减操作,所以目前的 age 的值为 19 alert(newAge); // 21,因为 --age 为前置递减,所以先递减后运算,此时 age 的值为18,再 + 2,所以值为 21 var num1 = 20; var num2 = 2; var num3 = --num2 + num1; // 21,先执行前num2的前置--操作,此时num2的值为 1,所以 1 + 20 = 21 var num4 = num2 + num1; // 21,此时经过上面的前置递减操作,num2的值已经变为 1,所以此处的num4的值应该为 21 var num1 = 20; var num2 = 2; var num3 = num2++ + num1; // 22,num2++为后置递加,所以此时不会进行递加运算, 2 + 20 = 22 var num4 = num2 + num1; // 23,此时经过上面的后置递加操作,num2的值已经变为 3,所以此处的num4的值应该为 23 ~~~ >[danger] 递增递减操作在用在其它数据类型中,会先将其转换为数值型,再进行递增或递减操作,如果不能转换为数字,则会转换为`NaN`,在应用到对象中时,会先调用对象中的`valueOf()`方法,取得一个可共操作的值,然后再对该值进行操作,如果结果是`NaN`,则再调用`toStrong()`方法后,再进行操作 #### 2、一元加和减操作符 一元加操作符是在需要操作的数值前面放一个加号(+),对数值不会产生任何影响,对于非数值,会自动转换为数值,如果转不了数值型,则会被转换为`NaN`。 一元减操作符主要用于表示负数,例如将正数转换为负数。 ~~~ var age = 20; var newAge = +age; //仍然是 20,不会变 var num1 = 20; var num2 = -num1; // -20,会被转换为负数 ~~~ ## 位作符 位操作符用于在最基本的层次上,即按内存中表示数值的位来操作数值。 ECMAScript 中的所有数值都以 IEEE-754 64 位格式存储,但位操作符并不直接操作 64 位的值。而是先将 64 位的值转换成 32 位的整数,然后执行操作,最后再将结果转换回 64 位。对于开发人员来说,由于 64 位存储格式是透明的,因此整个过程就像是只存在 32 位的整数一样。 对于有符号的整数, 32 位中的前 31 位用于表示整数的值。第 32 位用于表示数值的符号: 0 表示正数, 1 表示负数。这个表示符号的位叫做**符号位**,符号位的值决定了其他位数值的格式。其中,正数以纯二进制格式存储, 31 位中的每一位都表示 2 的幂。第一位(叫做位 0)表示 2<sup>0</sup>,第二位表示 2<sup>1</sup>,以此类 推 。 没 有 用 到 的 位 以 0 填 充 , 即 忽 略 不 计 。 例 如 , 数 值 18 的 二 进 制 表 示 是 `00000000000000000000000000010010`,或者更简洁的`10010`。这是 5 个有效位,这 5 位本身就决定了实际的值,如下图所示: :-: ![](https://box.kancloud.cn/2015-12-13_566d157d99d13.gif) 负数同样以二进制码存储,但使用的格式是二进制补码。计算一个数值的二进制补码,需要经过下列 3 个步骤: 1. 求这个数值绝对值的二进制码(例如,要求`-18`的二进制补码,先求`18`的二进制码); 2. 求二进制反码,即将`0`替换为 `1`,将`1`替换为`0`; 3. 得到的二进制反码加 1。 ~~~ // 要根据这 3 个步骤求得`-18`的二进制码,首先就要求得`18`的二进制码,即: 0000 0000 0000 0000 0000 0000 0001 0010 // 然后,求其二进制反码,即 0 和 1 互换: 1111 1111 1111 1111 1111 1111 1110 1101 // 最后,二进制反码加 1: 1111 1111 1111 1111 1111 1111 1110 1101 1 --------------------------------------- 1111 1111 1111 1111 1111 1111 1110 1110 // -18 的结果 ~~~ 要注意的是,在处理有符号整数时,是不能访问位 31 的。 #### 1、按位非(NOT) 按位非操作符由一个波浪线(~)表示,执行按位非的结果就是返回数值的反码。按位非是ECMAScript 操作符中少数几个与二进制计算有关的操作符之一。 ~~~ var num1 = 25; // 二进制 00000000000000000000000000011001 var num2 = ~num1; // 二进制 11111111111111111111111111100110 alert(num2); // -26 ~~~ #### 2、按位与(AND) 按位与操作符由一个和号字符(&)表示,它有两个操作符数。从本质上讲,按位与操作就是将两个数值的每一位对齐,然后根据下表中的规则,对相同位置上的两个数执行 AND 操作: ~~~ 第一个数的值 第二个数的值 结果 1 1 1 1 0 0 0 1 0 0 0 0 ~~~ 也就是说,按位与操作只在两个数值对应的对应位都是1时才返回1,否则返回的结果都是0。 #### 3、按位或(OR) 按位或操作符由一个竖线符号(|)表示,同样也有两个操作数。按位或操作遵循下面这个真值表。 ~~~ 第一个数的值 第二个数的值 结果 1 1 1 1 0 1 0 1 1 0 0 0 ~~~ 按位或中,两个数值对应位任何一个为`1`的时候,都返回`1`,只有两个都为`0`的时候,才返回`0`。 #### 4、按位异或(XOR) 按位异或操作符由一个插入符号(^)表示,也有两个操作数。以下是按位异或的真值表。 ~~~ 第一个数的值 第二个数的值 结果 1 1 0 1 0 1 0 1 1 0 0 0 ~~~ 按位异或与按位或的不同之处在于,这个操作在两个数值对应位上只有一个 `1` 时才返回 `1`,如果对应的两位都是 `1` 或都是 `0`,则返回 `0`。 #### 5、左移 左移操作符是由两个小于号(<<)组成,这个操作符会将数值的所有位向左移动指定的位数。例如将`2`(二进制码为`10`)向左移动5位,结果就是`64`(二进制码为1000000),向左侧移动后,多出的空位将用`0`来填充。左移不会影响被操作数的符号位。 ~~~ var oldValue = 2; // 等于二进制的 10 var newValue = oldValue << 5; // 等于二进制的 1000000,十进制的 64 ~~~ #### 6、有符号的右移 有符号的右移操作符由两个大于号(>>)表示,这个操作符会将数值向右移动,但保留符号位(即正负号标记)。有符号的右移操作与左移操作恰好相反,即如果将 64 向右移动 5 位,结果将变回 2: ~~~ var oldValue = 64; // 等于二进制的 1000000 var newValue = oldValue >> 5; // 等于二进制的 10 ,即十进制的 2 ~~~ #### 7、无符号的右移 无符号右移操作符由 3 个大于号(>>>)表示,这个操作符会将数值的所有 32 位都向右移动。对正数来说,无符号右移的结果与有符号右移相同。但是对负数来说,情况就不一样了。首先,无符号右移是以 0 来填充空位,而不是像有符号右移那样以符号位的值来填充空位。 ~~~ var oldValue = 64; // 等于二进制的 1000000 var newValue = oldValue >>> 5; // 等于二进制的 10 ,即十进制的 2 var oldValue = -64; // 等于二进制的 11111111111111111111111111000000 var newValue = oldValue >>> 5; // 00000111111111111111111111111110 等于十进制的 134217726 ~~~ ## 布尔操作符 布尔操作符一共有 3 个:非(NOT)、与(AND)和或(OR) #### 1、逻辑非 逻辑非操作符由一个叹号(!)表示,可以应用于 ECMAScript 中的任何值。无论这个值是什么数据类型,这个操作符都会返回一个布尔值。逻辑非操作符首先会将它的操作数转换为一个布尔值,然后再对其求反。 * 对象(包含空对象) ,返回 false * 空字符串,返回 true * 非空字符串,返回 false * 数值0,返回 true * 非 0 数值(包含 Infinity),返回 false * null,返回 true * NaN,返回 true * undefined 返回 true ~~~ var obj = {}; alert(!obj); // false alert(!false); // true alert(!"false") // false alert(!0); // true alert(!""); // true alert(!20); // false ~~~ #### 2、逻辑与(&&) 逻辑与操作符由两个和号(&&)表示,有左右两个操作数,如下面的例子所示: ~~~ var result = var1 && var2; ~~~ 逻辑与操作符,操作符两边的操作数都为 `true` 的情况下,才返回 `true`,否则都会返回 `false`。 ~~~ 第一个操作数 第二个操作数 结果 true true true true false false false true false false false false ~~~ 逻辑与操作可以应用于任何数据类型,但如果逻辑与操作符两边有一个操作数不是布尔值时,逻辑与操作就不一定会返回布尔值,此时,遵循以下规则 * 如果第一个操作数为对象,则返回第二个操作数 * 如果第二个操作数为对象,则只有在第一个操作数的结果为 true 的情况下,才会返回该对象,否则返回第一个操作数 * 如果两个操作数都为对象,则返回第二个操作数 * 如果第一个操作数为数值 0,则直接返回 0 * 如果第一个操作数为 false,则直接返回 false * 如果两个操作数中,出现 null,则直接返回 null * 如果两个操作数中,出现了NaN,则直接返回 NaN * 如果两个操作数据中,出现了 undefined,则直接返回 undefined 逻辑与操作属于短路操作,也就是说,只要第一个操作值为 false 的情况下,就不会去执行第二个操作值,而直接返回 false #### 3、 逻辑或(||) 逻辑或操作符由两个竖线符号(||)表示,也有左右两个操作数,逻辑或中,两边的操作数,只要有一个为 `true`,就返回 `true`,也就是说,只有两个操作数都为 `false` 的情况下,才返回 `false`。 与逻辑与操作相似,如果有一个操作数不是布尔值,逻辑或也不一定返回布尔值;此时,它遵循下列规则: * 如果第一个操作数是对象,则返回第一个操作数; * 如果第一个操作数的求值结果为 false,则返回第二个操作数; * 如果两个操作数都是对象,则返回第一个操作数; * 如果两个操作数都是 null,则返回 null; * 如果两个操作数都是 NaN,则返回 NaN; * 如果两个操作数都是 undefined,则返回 undefined。 与逻辑与操作符相似,逻辑或操作符也是短路操作符。也就是说,如果第一个操作数的求值结果为`true`,就不会对第二个操作数求值了。 ## 乘性操作符 ECMAScript 定义了 3 个乘性操作符:乘法、除法和求模(取余)。如果参与乘性计算的某个操作数不是数值,后台会先使用 `Number()`转型函数将其转换为数值。也就是说,空字符串将被当作`0`,布尔值 `true` 将被当作 `1`。 #### 1、乘法 乘法操作符是由一个星号(\*)表示,用来计算两个数的乘积。 ~~~ var result = 20 * 18; // 等于 360 ~~~ 在处理特殊值的情况下,乘法操作符遵循下列特殊的规则: * 如果操作数都是数值,执行常规的乘法计算,即两个正数或两个负数相乘的结果还是正数,而如果只有一个操作数有符号,那么结果就是负数。如果乘积超过了 ECMAScript 数值的表示范围,则返回 Infinity 或-Infinity; * 如果有一个操作数是 NaN,则结果是 NaN; * 如果是 Infinity 与 0 相乘,则结果是 NaN; * 如果是 Infinity 与非 0 数值相乘,则结果是 Infinity 或-Infinity,取决于有符号操作数的符号; * 如果是 Infinity 与 Infinity 相乘,则结果是 Infinity; * 如果有一个操作数不是数值,则在后台调用 Number()将其转换为数值,然后再应用上面的规则。 #### 2、除法 除法操作符由一个斜线(/)表示,执行第二个操作数第第一个操作数的计算。 ~~~ var result = 10 / 5; //等于 2 ~~~ #### 3、求模(取余) 求模(取余)操作符由一个百分号(%)表示。 ~~~ var result = 9 % 2; // 等于 1 ~~~ ## 加性操作符 加性操作符包括常用的加法和减法 #### 1、加法(+) ~~~ var result = 10 + 5; // 等于 15 ~~~ 如果加法操作符两边都是数值,则执行常规加法运算,然后返回相应的结果。但如果为其它类型的值,则遵循以下规则: * 如果有一个操作数是`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"`。 ~~~ var result = 20 + 20; // 40 两个操作值都为数值的情况下,直接进行相加运算 var result = 20 + "20"; // "2020",有一个操作值为字符串的情况下,直接进行字符串拼接 ~~~ #### 2、减法(-) ~~~ var result = 10 - 6; // 等于 4 ~~~ 与加法类似,如果两个操作数都为数值的情况下,直接进行减法运算后,返回运算结果,如果操作数为其它类型,则会进行转换。 ~~~ var result = 5 - 4; // 1,正常数值运算 var result = 5 - NaN; // NaN,如果有一个操作数为 NaN,则返回NaN var result = Infinity - Infinity; // NaN var result = -Infinity - -Infinity; // NaN var result = Infinity - -Infinity; // Infinity var result = -Infinity - Infinity; // -Infinity var result = 0 - 0; // 0 var result = 0 - -0; // -0 var result = -0 - -0; // 0 var result = 20 - true; // 19,true 被转换为了 1 var result = 20 - ""; // 20,"" 被转换为了 0 var result = 20 - "2"' // 18,"2" 被转换为了 2 var result = 20 - null; // 20,null 被转换为了 0 ~~~ >[danger] 如果有一个操作数是字符串、布尔值、 `nul`l 或 `undefined`,则先在后台调用 `Number()`函数将其转换为数值,然后再根据前面的规则执行减法计算。如果转换的结果是 `NaN`,则减法的结果就是 `NaN`; >如果有一个操作数是对象,则调用对象的 `valueOf()`方法以取得表示该对象的数值。如果得到的值是 NaN,则减法的结果就是 `NaN`。如果对象没有 `valueOf()`方法,则调用其 `toString()`方法并将得到的字符串转换为数值。 ## 关系操作符 关系操作符包含:大于(>),小于(<)、大于等于(>=),小于等于(<=),这几个操作符都返回为布尔值,成立则返回 `true`,否则返回 `false`。 如果两个操作数都是数值型,则直接进行比较,如果两个都为英文字符串,则比较其对应的字符串编码值。否则会将其转换为数值型再进行比较。 ~~~ var result = 5 > 3; // true var result = 5 < 3; // false var result = "red" > "blue"; // true,会比较其它字符编码 var result = "23" < "3"; // true,因为在两个字符串进行比较时,会直接比较其字符编码,而不会进行转换 ~~~ ## 相等操作符 #### 1、相等和不相等(== 和 !=) ECMAScript中,相等操作符是由两个等号(==)表示,如果两个操作数相等,则返回`true`,否则返回`false`。 不相等用叹号和等号(!=)表示,与相等(==)刚好相反,两个操作数不相等的情况下,返回`true`,否则返回`false`。在进行相等和不相等时,会自动转换为相同的数据类型再进行比较。 ~~~ alert(1 == true); // true,true 会自动转换为 1 alert(5 == "5"); // true,"5" 会自动转换为 5 alert(null == undefined); // true alert(NaN == NaN); // false,NaN不与任何值相等,包括它自己 alert(NaN != NaN); // true alert(undefined == 0); // false ~~~ #### 2、全等和不全等(=== 和 !==) 全等是由三个等号(===)表示,全等不会进行数据转换而直接进行比较,相同返回 `true`,否则返回 `false`。 不全等刚好和全等相反,两边不全等时返回 `true`,两边全等则返回 `false`。 ~~~ var result = 20 == "20"; // true,会将 "20"转换为 20 var result = 20 === "20"; // false,不会进行转换,直接比较 var result = 20 != "20"; // false var result = 20 !=="20"; // true ~~~ ## 条件操作符(三元运算符) 条件运算符也叫三元运算符。三元运算符是各种编程语言中非常常用的一种运算符,一般用于比较或赋值当中,其语法格式为: ~~~ variable = boolean_expression ? true_value : false_value; ~~~ 以上这行代码表示,根据表达式`boolean_expression`的结果给 `variable`赋值,如果表达式 `boolean_expression`成立,则执行问号(?)后面、冒号(:)前面的代码,否则执行冒号(:)后面的代码,也就是说,如果表达式`boolean_expression`成立,则将`true_value`赋值给`variable`,否则将`false_value`赋值给`variable`。 ~~~ var num1 = 5; var num2 = 3; var num3 = (num1 > num2) ? num1 : num2; // 3 (num1 > num2) ? num2++ : num1++; //如果num1 大于num2的话,那么给num2递增,否则给num1递增 alert(num2); // 4, alert(num1); // 5 ~~~ ## 赋值操作符 赋值操作符是用一个等号(=)表示,是用来将右则的值赋给左侧的变量。如果在等于号(=)前面再添加乘性操作符、加性操作符或位操作符,就可以完成复合赋值操作。 ~~~ var age = 20; // 常规赋值操作 age += 1; // 相当于 age = age + 1; alert(age); // 21 ~~~ 常见的复合赋值操作如下: * 乘/赋值(*=) * 除/赋值(/=) * 模/赋值(%=) * 加/赋值(+=) * 减/赋值(=) * 左移/赋值(<<=) * 有符号右移/赋值(>>=) * 无符号右移/赋值(>>>=) >[danger] 设计这些操作符的主要目的就是简化赋值操作。使用它们不会带来任何性能的提升 ## 逗号操作符 使用逗号操作符可以在一条语句中执行多个操作,常用于赋值操作,一次给多个变量赋值。 ~~~ var num1 = 1, num2 = 2, num3 = 3; var num4,num5,num6 = 4,5,6; ~~~