有关 JavaScript 的值相等

Abiee,

如果你有使用 JavaScript 的经验,想必至少见过下列其中一种表达式:

严格相等:a === b

松散相等:a == b

值相等:Object.is(a, b)

松散相等

在编码中,我们经常要判断两个值是否相等,究竟该用 ”===” 还是 ”==” ?这是个老生常谈的话题。在过去,大多数 JavaScript 的学习资料都存在“偷懒”行为:

<input id="count" type="number" />

在该输入框中,我们输入的数字始终都是“字符数字”,判断它是否等于 10 用 ”==” 完全符合预期,因为 JavaScript 会自动完成类型转换。

这种“偷懒”常常产生误导,以下是两个让你毛骨悚然的例子:

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

到底发生了什么事情?

松散相等非常晦涩,在许多现代的编码中,完全禁止使用 ==!= 。如果你对它原理敢兴趣,可以查看 Equality comparisons and sameness,我不愿在此讨论如此复杂的问题。

小技巧

在上述判断输入框中数值大小的例子中,将 string 类型数字转换为 number 类型可以这样书写:

let value = '10';
+value === 10; // true

从而避免使用 Number(value)

严格相等

相信大家都很熟悉 === ,这里不再做赘述,但是有两个特例:

  • NaN === NaN 是 false,尽管它们是相同的值
  • -0 === 0 或者 0 === -0 是 true,尽管它们是不同的值
const a = NaN;
const b = a;
console.log(a === b); // false
console.log(NaN === NaN); // false

console.log(0 === -0); // true
console.log(-0 === 0); // true

Object.is(value1, value2)

对于严格相等的“两个例外”,我们该怎么判断让它符合预期呢?Object.is() 方法正好可以解决,它还适用于对象。

console.log(Object.is(NaN, NaN)); // true
console.log(Object.is(0, -0)); // false

console.log(Object.is({}, {})); // false

const obj1 = {};
const obj2 = obj1;
console.log(Object.is(obj1, obj2)); // true