• 操作符


    操作符包括数学操作符(如加、减)、位操作符、关系操作符和相等操作符等。
    操作符是独特的,因为它们可用于各种值,包括字符串、数值、布尔值,甚至还有对象。在应用给对象时,操作符通常会调用 valueOf()和/或 toString()方法来取得可以计算的值
    一元操作符
    只操作一个值的操作符叫一元操作符
    1.递增/递减操作符
    有两个版本:前缀版和后缀版;前缀版就是位于要操作的变量前头,后缀版就是位于要操作的变量后头
    let age = 29; 
    ++age;
    前缀递增操作符把 age 的值变成了 30(给之前的值 29 加 1)
    let age = 29; 
    --age;
    无论使用前缀递增还是前缀递减操作符,变量的值都会在语句被求值之前改变
    let age = 29; 
    let anotherAge = --age + 2; 
    console.log(age); // 28 
    console.log(anotherAge); // 30
    前缀递增和递减在语句中的优先级是相等的,因此会从左到右依次求值
    let num1 = 2; 
    let num2 = 20; 
    let num3 = --num1 + num2; 
    let num4 = num1 + num2; 
    console.log(num3); // 21 
    console.log(num4); // 21
    递增和递减的后缀版语法一样(分别是++和--),只不过要放在变量后面。后缀版与前缀版的主要区别在于,后缀版递增和递减在语句被求值后才发生
    let num1 = 2; 
    let num2 = 20; 
    let num3 = num1-- + num2; 
    let num4 = num1 + num2;
    console.log(num3); // 22 
    console.log(num4); // 21
    这 4 个操作符可以作用于任何值,意思是不限于整数——字符串、布尔值、浮点值,甚至对象都可以
    1. 对于字符串,如果是有效的数值形式,则转换为数值再应用改变。变量类型从字符串变成数值
    2. 对于字符串,如果不是有效的数值形式,则将变量的值设置为 NaN 。变量类型从字符串变成数值
    3. 对于布尔值,如果是 false,则转换为 0 再应用改变。变量类型从布尔值变成数值
    4. 对于布尔值,如果是 true,则转换为 1 再应用改变。变量类型从布尔值变成数值
    5. 对于浮点值,加 1 或减 1
    6. 如果是对象,则调用其valueOf()方法取得可以操作的值。对得到的值应用上述规则。如果是 NaN,则调用 toString()并再次应用其他规则。变量类型从对象变成数值
    let s1 = "2"; 
    let s2 = "z"; 
    let b = false; 
    let f = 1.1; 
    let o = { 
     valueOf() { 
     return -1; 
     } 
    }; 
    s1++; // 值变成数值 3 
    s2++; // 值变成 NaN 
    b++; // 值变成数值 1 
    f--; // 值变成 0.10000000000000009(因为浮点数不精确)
    o--; // 值变成-2
    2. 一元加和减
    一元加由一个加号(+)表示,放在变量前头,对数值没有任何影响
    let num = 25; 
    num = +num; 
    console.log(num); // 25
    将一元加应用到非数值,则会执行与使用 Number()转型函数一样的类型转换:布尔值 false和 true 转换为 0 和 1,字符串根据特殊规则进行解析,对象会调用它们的 valueOf()和/或 toString()方法以得到可以转换的值
    let s1 = "01"; 
    let s2 = "1.1";
    let s3 = "z"; 
    let b = false; 
    let f = 1.1; 
    let o = { 
     valueOf() { 
     return -1; 
     } 
    }; 
    s1 = +s1; // 值变成数值 1 
    s2 = +s2; // 值变成数值 1.1 
    s3 = +s3; // 值变成 NaN 
    b = +b; // 值变成数值 0 
    f = +f; // 不变,还是 1.1 
    o = +o; // 值变成数值-1
    一元减由一个减号(-)表示,放在变量前头,主要用于把数值变成负值,如把1 转换为-1
    let num = 25; 
    num = -num; 
    console.log(num); // -25
    对数值使用一元减会将其变成相应的负值(如上面的例子所示)。在应用到非数值时,一元减会遵循与一元加同样的规则,先对它们进行转换,然后再取负值
    let s1 = "01"; 
    let s2 = "1.1"; 
    let s3 = "z"; 
    let b = false; 
    let f = 1.1; 
    let o = { 
     valueOf() { 
     return -1; 
     } 
    }; 
    s1 = -s1; // 值变成数值-1 
    s2 = -s2; // 值变成数值-1.1 
    s3 = -s3; // 值变成 NaN 
    b = -b; // 值变成数值 0 
    f = -f; // 变成-1.1 
    o = -o; // 值变成数值 1
    位操作符
    ECMAScript中的所有数值都以 IEEE 754 64 位格式存储,但位操作并不直接应用到 64 位表示,而是先把值转换为32 位整数,再进行位操作,之后再把结果转换为 64 位。对开发者而言,就好像只有 32 位整数一样,因为 64 位整数存储格式是不可见的
    有符号整数使用 32 位的前 31 位表示整数值。第 32 位表示数值的符号,如 0 表示正,1 表示负。这一位称为符号位(sign bit),它的值决定了数值其余部分的格式。
    正值以真正的二进制格式存储,即 31位中的每一位都代表 2 的幂。第一位(称为第 0 位)表示 20 ,第二位表示 21 ,依此类推。如果一个位是空的,则以0填充,相当于忽略不计
    数值18的二进制格式为00000000000000000000000000010010,或更精简的 10010
    负值以一种称为二补数(或补码)的二进制编码存储
    一个数值的二补数通过如下 3 个步骤计算得到
    1. 确定绝对值的二进制表示(如,对于18,先确定 18 的二进制表示)
    2. 找到数值的一补数(或反码),换句话说,就是每个 0 都变成 1,每个 1 都变成 0;
    3. 给结果加 1
    基于上述步骤确定18 的二进制表示,首先从 18 的二进制表示开始:
    0000 0000 0000 0000 0000 0000 0001 0010
    然后,计算一补数,即反转每一位的二进制值:
    1111 1111 1111 1111 1111 1111 1110 1101
    最后,给一补数加 1:
    1111 1111 1111 1111 1111 1111 1110 1110
    -18 的二进制表示就是 11111111111111111111111111101110。要注意的是,在处理有符号整数时,我们无法访问第 31 位
    ECMAScript 会帮我们记录这些信息。在把负值输出为一个二进制字符串时,我们会得到一个前面加了减号的绝对值
    let num = -18; 
    console.log(num.toString(2)); // "-10010"
    转换过程会求得二补数,然后再以更符合逻辑的形式表示出来
    在对 ECMAScript 中的数值应用位操作符时,后台会发生转换:64 位数值会转换为 32 位数值,然后执行位操作,最后再把结果从 32 位转换为 64 位存储起来。
    但这个转换也导致了一个奇特的副作用,即特殊值NaN 和Infinity在位操作中都会被当成 0 处理。
    如果将位操作符应用到非数值,那么首先会使用 Number()函数将该值转换为数值(这个过程是自动的),然后再应用位操作。最终结果是数值
    1. 按位非
    按位非操作符用波浪符(~)表示,它的作用是返回数值的一补数。按位非是ECMAScript 中为数不多的几个二进制数学操作符之一
    let num1 = 25; // 二进制 00000000000000000000000000011001 
    let num2 = ~num1; // 二进制 11111111111111111111111111100110 
    console.log(num2); // -26
    按位非操作符作用到了数值 25,得到的结果是26。由此可以看出,按位非的最终效果是对数值取反并减 1,就像执行如下操作的结果一样
    let num1 = 25; 
    let num2 = -num1 - 1; 
    console.log(num2); // "-26"
    尽管两者返回的结果一样,但位操作的速度快得多。这是因为位操作是在数值的底层表示上完成的
    2. 按位与
    按位与操作符用和号(&)表示,有两个操作数。本质上,按位与就是将两个数的每一个位对齐,然后基于真值表中的规则,对每一位执行相应的与操作
    按位与操作在两个位都是 1 时返回 1,在任何一位是 0 时返回 0
    let result = 25 & 3; 
    console.log(result); // 1
    25 和 3 的按位与操作的结果是 1。为什么呢?看下面的二进制计算过程

    3. 按位或

    按位或操作符用管道符(|)表示,同样有两个操作数。按位或遵循如下真值表
    按位或操作在至少一位是 1 时返回 1,两位都是 0 时返回 0
    let result = 25 | 3; 
    console.log(result); // 27

     4. 按位异或

    按位异或用脱字符(^)表示,同样有两个操作数

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

    let result = 25 ^ 3; 
    console.log(result); // 26

     5. 左移

    左移操作符用两个小于号(<<)表示,会按照指定的位数将数值的所有位向左移动
    let oldValue = 2; // 等于二进制 10 
    let newValue = oldValue << 5; // 等于二进制 1000000,即十进制 64
    左移会保留它所操作数值的符号。比如,如果2 左移 5 位,将得到64,而不是正 64
    6. 有符号右移
    有符号右移由两个大于号(>>)表示,会将数值的所有 32 位都向右移,同时保留符号(正或负)
    let oldValue = 64; // 等于二进制 1000000 
    let newValue = oldValue >> 5; // 等于二进制 10,即十进制 2
    7. 无符号右移
    无符号右移用 3 个大于号表示(>>>),会将数值的所有 32 位都向右移。对于正数,无符号右移与有符号右移结果相同
    let oldValue = 64; // 等于二进制 1000000 
    let newValue = oldValue >>> 5; // 等于二进制 10,即十进制 2
    对于负数,有时候差异会非常大。与有符号右移不同,无符号右移会给空位补 0,而不管符号位是什么。对正数来说,这跟有符号右移效果相同。但对负数来说,结果就差太多了。无符号右移操作符将负数的二进制表示当成正数的二进制表示来处理。因为负数是其绝对值的二补数,所以右移之后结果变得非常之大
    let oldValue = -64; // 等于二进制 11111111111111111111111111000000 
    let newValue = oldValue >>> 5; // 等于十进制 134217726
    布尔操作符
    1. 逻辑非
    逻辑非操作符由一个叹号(!)表示,可应用给 ECMAScript 中的任何值。这个操作符始终返回布尔值,无论应用到的是什么数据类型。逻辑非操作符首先将操作数转换为布尔值,然后再对其取反
    • 如果操作数是对象,则返回 false
    • 如果操作数是空字符串,则返回 true
    • 如果操作数是非空字符串,则返回 false
    • 如果操作数是数值 0,则返回 true
    • 如果操作数是非 0 数值(包括 Infinity),则返回 false
    • 如果操作数是 null,则返回 true
    • 如果操作数是 NaN,则返回 true
    • 如果操作数是 undefined,则返回 true
    console.log(!false); // true 
    console.log(!"blue"); // false 
    console.log(!0); // true 
    console.log(!NaN); // true 
    console.log(!""); // true 
    console.log(!12345); // false
    逻辑非操作符也可以用于把任意值转换为布尔值。同时使用两个叹号(!!),相当于调用了转型函Boolean()。无论操作数是什么类型,第一个叹号总会返回布尔值。第二个叹号对该布尔值取反,从而给出变量真正对应的布尔值。结果与对同一个值使用 Boolean()函数是一样的
    console.log(!!"blue"); // true 
    console.log(!!0); // false 
    console.log(!!NaN); // false 
    console.log(!!""); // false 
    console.log(!!12345); // true
    2. 逻辑与
    逻辑与操作符由两个和号(&&)表示,应用到两个值

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

    • 如果第一个操作数是对象,则返回第二个操作数
    • 如果第二个操作数是对象,则只有第一个操作数求值为
    • 如果两个操作数都是对象,则返回第二个操作数
    • 如果有一个操作数是 null,则返回 null
    • 如果有一个操作数是 NaN,则返回 NaN
    • 如果有一个操作数是 undefined,则返回 undefined
    逻辑与操作符是一种短路操作符,意思就是如果第一个操作数决定了结果,那么永远不会对第二个操作数求值。对逻辑与操作符来说,如果第一个操作数是 false,那么无论第二个操作数是什么值,结果也不可能等于 true
    let found = true; 
    let result = (found && someUndeclaredVariable); // 这里会出错
    console.log(result); // 不会执行这一行
    上面的代码之所以会出错,是因为 someUndeclaredVariable 没有事先声明,所以当逻辑与操作符对它求值时就会报错。变量 found 的值是 true,逻辑与操作符会继续求值变量 someUndeclaredVariable但是由于 someUndeclaredVariable 没有定义,不能对它应用逻辑与操作符,因此就报错了
    let found = false; 
    let result = (found && someUndeclaredVariable); // 不会出错
    console.log(result); // 会执行
    3. 逻辑或
    逻辑或操作符由两个管道符(||)表示

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

    • 如果第一个操作数是对象,则返回第一个操作数
    • 如果第一个操作数求值为 false,则返回第二个操作数
    • 如果两个操作数都是对象,则返回第一个操作数
    • 如果两个操作数都是 null,则返回 null
    • 如果两个操作数都是 NaN,则返回 NaN
    • 如果两个操作数都是 undefined,则返回 undefined
    同样与逻辑与类似,逻辑或操作符也具有短路的特性。只不过对逻辑或而言,第一个操作数求值为true,第二个操作数就不会再被求值了
    let found = true; 
    let result = (found || someUndeclaredVariable); // 不会出错
    console.log(result); // 会执行
    let found = false; 
    let result = (found || someUndeclaredVariable); // 这里会出错
    console.log(result); // 不会执行这一行
    利用这个行为,可以避免给变量赋值 null undefined
    let myObject = preferredObject || backupObject;
    变量 myObject 会被赋予两个值中的一个。其中,preferredObject 变量包含首选的值,backupObject 变量包含备用的值。如果 preferredObject 不是 null,则它的值就会赋给myObject;如果 preferredObject null,则 backupObject 的值就会赋给 myObject
    乘性操作符
    ECMAScript 定义了 3 个乘性操作符:乘法、除法和取模
    如果乘性操作符有不是数值的操作数,则该操作数会在后台被使用 Number()转型函数转换为数值。这意味着空字符串会被当成 0,而布尔值 true 会被当成 1
    1. 乘法操作符
    乘法操作符由一个星号(*)表示,可以用于计算两个数值的乘积
    let result = 34 * 56;
    乘法操作符在处理特殊值时也有一些特殊的行为
    • 如果操作数都是数值,则执行常规的乘法运算,即两个正值相乘是正值,两个负值相乘也是正值,正负符号不同的值相乘得到负值。如果 ECMAScript 不能表示乘积,则返回 Infinity -Infinity
    • 如果有任一操作数是 NaN,则返回 NaN
    • 如果是 Infinity 乘以 0,则返回 NaN
    • 如果是 Infinity 乘以非 0的有限数值,则根据第二个操作数的符号返回 Infinity -Infinity
    • 如果是 Infinity 乘以 Infinity,则返回 Infinity
    • 如果有不是数值的操作数,则先在后台用 Number()将其转换为数值,然后再应用上述规则
    2. 除法操作符
    除法操作符由一个斜杠(/)表示,用于计算第一个操作数除以第二个操作数的商
    let result = 66 / 11;
    跟乘法操作符一样,除法操作符针对特殊值也有一些特殊的行为
    • 如果操作数都是数值,则执行常规的除法运算,即两个正值相除是正值,两个负值相除也是正值,符号不同的值相除得到负值。如果ECMAScript不能表示商,则返回Infinity-Infinit
    • 如果有任一操作数是 NaN,则返回 NaN
    • 如果是 Infinity 除以 Infinity,则返回 NaN
    • 如果是 0 除以 0,则返回 NaN
    • 如果是非 0 的有限值除以 0,则根据第一个操作数的符号返回 Infinity -Infinity
    • 如果是 Infinity 除以任何数值,则根据第二个操作数的符号返回 Infinity -Infinity
    • 如果有不是数值的操作数,则先在后台用 Number()函数将其转换为数值,然后再应用上述规则
    3. 取模操作符
    取模(余数)操作符由一个百分比符号(%)表示
    let result = 26 % 5; // 等于 1
    与其他乘性操作符一样,取模操作符对特殊值也有一些特殊的行为
    • 如果操作数是数值,则执行常规除法运算,返回余数
    • 如果被除数是无限值,除数是有限值,则返回NaN
    • 如果被除数是有限值,除数是 0,则返回 NaN
    • 如果是 Infinity 除以 Infinity,则返回 NaN
    • 如果被除数是有限值,除数是无限值,则返回被除数
    • 如果被除数是 0,除数不是 0,则返回 0
    • 如果有不是数值的操作数,则先在后台用 Number()函数将其转换为数值,然后再应用上述规则
    指数操作符
    ECMAScript 7 新增了指数操作符,Math.pow()现在有了自己的操作符**
    console.log(Math.pow(3, 2); // 9 
    console.log(3 ** 2); // 9 
    console.log(Math.pow(16, 0.5); // 4 
    console.log(16** 0.5); // 4
    指数操作符也有自己的指数赋值操作符**=,该操作符执行指数运算和结果的赋值操作
    let squared = 3; 
    squared **= 2; 
    console.log(squared); // 9
    
    let sqrt = 16; 
    sqrt **= 0.5; 
    console.log(sqrt); // 4
    加性操作符
     加性操作符,即加法和减法操作符
     1. 加法操作符
    加法操作符(+)用于求两个数的和
    如果两个操作数都是数值,加法操作符执行加法运算并根据如下规则返回结果
    • 如果有任一操作数是 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"
    let result1 = 5 + 5; // 两个数值
    console.log(result1); // 10 
    let result2 = 5 + "5"; // 一个数值和一个字符串
    console.log(result2); // "55"

     ECMAScript 中最常犯的一个错误,就是忽略加法操作中涉及的数据类型

    let num1 = 5; 
    let num2 = 10; 
    let message = "The sum of 5 and 10 is " + num1 + num2; 
    console.log(message); // "The sum of 5 and 10 is 510"
    变量 message 中保存的是一个字符串,是执行两次加法操作之后的结果。有人可能会认为最终得到的字符串是"The sum of 5 and 10 is 15"。可是,实际上得到的是"The sum of 5 and 10is 510"。这是因为每次加法运算都是独立完成的。第一次加法的操作数是一个字符串和一个数值(5),结果还是一个字符串。第二次加法仍然是用一个字符串去加一个数值(10),同样也会得到一个字符串。如果想真正执行数学计算,然后把结果追加到字符串末尾,只要使用一对括号即可
    let num1 = 5; 
    let num2 = 10; 
    let message = "The sum of 5 and 10 is " + (num1 + num2); 
    console.log(message); // "The sum of 5 and 10 is 15"
    2. 减法操作符
    减法操作符(-)
    let result = 2 - 1;
    与加法操作符一样,减法操作符也有一组规则用于处理 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()方法,然后再将得到的字符串转换为数值
    let result1 = 5 - true; // true 被转换为 1,所以结果是 4 
    let result2 = NaN - 1; // NaN 
    let result3 = 5 - 3; // 2 
    let result4 = 5 - ""; // ""被转换为 0,所以结果是 5 
    let result5 = 5 - "2"; // "2"被转换为 2,所以结果是 3 
    let result6 = 5 - null; // null 被转换为 0,所以结果是 5
    关系操作符
    关系操作符执行比较两个值的操作,包括小于(<)、大于(>)、小于等于(<=)和大于等于(>=),用法跟数学课上学的一样。这几个操作符都返回布尔值
    let result1 = 5 > 3; // true 
    let result2 = 5 < 3; // false
    与 ECMAScript 中的其他操作符一样,在将它们应用到不同数据类型时也会发生类型转换和其他行为
    • 如果操作数都是数值,则执行数值比较
    • 如果操作数都是字符串,则逐个比较字符串中对应字符的编码
    • 如果有任一操作数是数值,则将另一个操作数转换为数值,执行数值比较
    • 如果有任一操作数是对象,则调用其 valueOf()方法,取得结果后再根据前面的规则执行比较。如果没有 valueOf()操作符,则调用 toString()方法,取得结果后再根据前面的规则执行比较
    • 如果有任一操作数是布尔值,则将其转换为数值再执行比较
    let result = "Brick" < "alphabet"; // true
    在这里,字符串"Brick"被认为小于字符串"alphabet",因为字母 B 的编码是 66,字母 a 的编码是 97。要得到确实按字母顺序比较的结果,就必须把两者都转换为相同的大小写形式(全大写或全小写),然后再比较
    let result = "Brick".toLowerCase() < "alphabet".toLowerCase(); // false
    let result = "23" < "3"; // true
    这里在比较字符串"23"和"3"时返回 true。因为两个操作数都是字符串,所以会逐个比较它们的字符编码(字符"2"的编码是 50,而字符"3"的编码是 51)。不过,如果有一个操作数是数值,那么比较的结果就对了
    let result = "23" < 3; // false
    let result = "a" < 3; // 因为"a"会转换为 NaN,所以结果是 false
    因为字符"a"不能转换成任何有意义的数值,所以只能转换为 NaN。这里有一个规则,即任何关系操作符在涉及比较 NaN 时都返回 false
    let result1 = NaN < 3; // false 
    let result2 = NaN >= 3; // false
    在大多数比较的场景中,如果一个值不小于另一个值,那就一定大于或等于它。但在比较 NaN 时,无论是小于还是大于等于,比较的结果都会返回 false
    相等操作符
    判断两个变量是否相等是编程中最重要的操作之一。在比较字符串、数值和布尔值是否相等时,过程都很直观。但是在比较两个对象是否相等时,情形就比较复杂了
    ECMAScript提供了两组操作符。第一组是等于和不等于,它们在比较之前执行转换。第二组是全等和不全等,它们在比较之前不执行转换
    1. 等于和不等于
    等于操作符用两个等于号(==)表示,如果操作数相等,则会返回 true。不等于操作符用叹号和等于号(!=)表示,如果两个操作数不相等,则会返回 true。这两个操作符都会先进行类型转换(通常称为强制类型转换)再确定操作数是否相等
    在转换操作数的类型时,相等和不相等操作符遵循如下规则
    • 如果任一操作数是布尔值,则将其转换为数值再比较是否相等。false 转换为 0,true 转换为 1
    • 如果一个操作数是字符串,另一个操作数是数值,则尝试将字符串转换为数值,再比较是否相等
    • 如果一个操作数是对象,另一个操作数不是,则调用对象的 valueOf()方法取得其原始值,再根据前面的规则进行比较
    在进行比较时,这两个操作符会遵循如下规则
    • null 和 undefined 相等
    • null 和 undefined 不能转换为其他类型的值再进行比较
    • 如果有任一操作数是 NaN,则相等操作符返回 false,不相等操作符返回 true。记住:即使两个操作数都是 NaN,相等操作符也返回 false,因为按照规则,NaN 不等于 NaN
    • 如果两个操作数都是对象,则比较它们是不是同一个对象。如果两个操作数都指向同一个对象,则相等操作符返回 true。否则,两者不相等
    下表总结了一些特殊情况及比较的结果
    表 达 式
    结 果
    null == undefined
    true
    "NaN" == NaN
    false
    5 == NaN
    false
    NaN == NaN
    false
    NaN != NaN
    true
    false == 0
    true
    true == 1
    true
    true == 2
    false
    undefined == 0
    false
    null == 0
    false
    "5" == 5
    true
    2. 全等和不全等
    全等和不全等操作符与相等和不相等操作符类似,只不过它们在比较相等时不转换操作数。全等操作符由 3 个等于号(===)表示,只有两个操作数在不转换的前提下相等才返回 true
    let result1 = ("55" == 55); // true,转换后相等
    let result2 = ("55" === 55); // false,不相等,因为数据类型不同
    不全等操作符用一个叹号和两个等于号(!==)表示,只有两个操作数在不转换的前提下不相等才返回 true
    let result1 = ("55" != 55); // false,转换后相等
    let result2 = ("55" !== 55); // true,不相等,因为数据类型不同
    虽然 null == undefined 是 true(因为这两个值类似),但 null === undefined 是false,因为它们不是相同的数据类型
    条件操作符
    variable = boolean_expression ? true_value : false_value;
    上面的代码执行了条件赋值操作,即根据条件表达式 boolean_expression 的值决定将哪个值赋给变量 variable 。如果 boolean_expression 是 true ,则赋值 true_value ;如果boolean_expression 是 false,则赋值 false_value
    赋值操作符
    简单赋值用等于号(=)表示,将右手边的值赋给左手边的变量
    let num = 10
    复合赋值使用乘性、加性或位操作符后跟等于号(=)表示。这些赋值操作符是类似如下常见赋值操作的简写形式
    let num = 10; 
    num = num + 10;
    每个数学操作符以及其他一些操作符都有对应的复合赋值操作符
    • 乘后赋值(*=)
    • 除后赋值(/=)
    • 取模后赋值(%=)
    • 加后赋值(+=)
    • 减后赋值(-=)
    • 左移后赋值(<<=)
    • 右移后赋值(>>=)
    • 无符号右移后赋值(>>>=)
    逗号操作符
    逗号操作符可以用来在一条语句中执行多个操作
    let num1 = 1, num2 = 2, num3 = 3;
    在一条语句中同时声明多个变量是逗号操作符最常用的场景。不过,也可以使用逗号操作符来辅助赋值。在赋值时使用逗号操作符分隔值,最终会返回表达式中最后一个值
    let num = (5, 1, 4, 8, 0); // num 的值为 0
    在这个例子中,num 将被赋值为 0,因为 0 是表达式中最后一项。逗号操作符的这种使用场景并不多见,但这种行为的确存在
  • 相关阅读:
    Java高级部分--工具类(1)
    Javascript 与正则表达式
    Java基础部分--面向对象基础(1)
    Java基础部分--面向对象高级特性(2)
    持久层框架--hibernate(4)
    持久层框架--hibernate(3)
    持久层框架--hibernate(2)
    python常见面试题
    单元测试之写用例(全局变量,异常处理,断言)
    jmeter安装踩坑记录
  • 原文地址:https://www.cnblogs.com/dropInInt/p/14890397.html
Copyright © 2020-2023  润新知