头像

JS 中的相等性判断

JavaScript 提供三种不同的比较操作符:

  • 严格相等,使用 ===
  • (非严格)相等,使用 ==
  • 以及 Object.is。(ES 6 新特性)

严格相等 ===

  • 一个值只与自身全等。
  • 浮点数 0 不分正负,全等操作符认为 +0-0 全等。
  • 全等操作符认为 NaN 与其他任何值都不全等,包括它自己。(等式 (x !== x) 成立的唯一情况是 x 的值为 NaN
1
2
3
4
5
6
console.log(-0 === +0); // true
console.log(-1 === +1); // false
console.log(NaN === NaN); // false

console.log(null === null); // true
console.log(undefined === undefined); // true

非严格相等 ==

  • 相等操作符比较两个值是否相等,在比较前将两个被比较的值转换为相同类型 (String、Boolean 都会先转化为 number 型)
  • 在转换后(等式的一边或两边都可能被转换),最终的比较方式等同于全等操作符 === 的比较方式。
  • 相等操作符满足交换律。
1
2
3
4
5
6
7
console.log(2 == true); // false
console.log('2' == true); // false
console.log(2 == false); // false
console.log('2' == false); // false

console.log(1 == true); // true
console.log(0 == false); // true

注意: 进行非严格相等比较时,布尔值会转化为 number 型,true -> 1,false -> 0

Object.is

Object.is(value1, value2);

返回一个布尔值,表明传入的两个值是否是同一个值。

1
2
3
Object.is([], []); // false
Object.is(-0, +0); // false
Object.is(NaN, NaN); // true

=== == Object.is 比较

image

一些例题

奇特的 ++[[]][+[]]+[+[]]

1
2
let c = ++[[]][+[]] + [+[]];
console.log(c); // 10

复习: 运算符优先级(MDN)

详细计算过程:

  1. 先把 ++[[]][+[]]+[+[]] 分解一下:

    1
    ++[[]][+[]] + [+[]];
  2. 在 JS 里,+ 可以把其他类型转化成 number,这里可以把空数组转化成 0:

    1
    console.log(+[] === 0); // true

    所以 ++[[]][+[]]+[+[]] 变成:

    1
    ++[[]][0] + [0];
  3. [[]][0] 表示从 [[]] 中取出第一个元素,所以:

    1
    ++[] + [0]
  4. 步骤 2 里说过 + 可以把其他类型转化成 number++ 也可以把其他类型转化成 number,并且再增加 1:

    1
    1 + [0];
  5. 在 JS 中 [0] == '0' 是真:

    1
    console.log([0] == '0'); // true

    所以:

    1
    1 + '0';
  6. 最后 ++[[]][+[]]+[+[]] 转化为 1 + '0'number + string = string,所以最后得 '10'

参考: