为什么 [NaN].include(NaN) 在 JavaScript 中返回 true?

2022-08-30 04:20:52

我很熟悉JavaScript中的“怪异”,即总是返回,如此处所述。因此,人们不应该进行比较来检查,而应该使用isNaN(..)代替。NaNNaN === NaNfalse===NaN

所以我惊讶地发现

> [NaN].includes(NaN)
true

这似乎不一致。为什么会有这种行为?

它是如何工作的?该方法是否专门检查?includesisNaN


答案 1

根据MDN的文件

注意:从技术上讲,include() 使用相同的ValueZero算法来确定是否找到给定的元素。

const x = NaN, y = NaN;
console.log(x == y); // false                -> using ‘loose’ equality
console.log(x === y); // false               -> using ‘strict’ equality
console.log([x].indexOf(y)); // -1 (false)   -> using ‘strict’ equality
console.log(Object.is(x, y)); // true        -> using ‘Same-value’ equality
console.log([x].includes(y)); // true        -> using ‘Same-value-zero’ equality

更详细的说明:

  1. 相同值零相等类似于相同值相等但 +0 和 −0 被视为相等
  2. Object.is() 方法提供相同值相等:和 之间的唯一区别在于它们对有符号零和 NaN 的处理。Object.is()===

enter image description here


其他资源:


答案 2

该方法使用SameValueZero算法来检查两个值的相等性,并且它认为该值等于自身。.includes()NaN

SameValueZero 算法与 SameValue 类似,但唯一的区别是 SameValueZero 算法认为并且是相等的。+0-0

该方法使用 SameValue,并且返回 true for 。Object.is()NaN

console.log(Object.is(NaN, NaN));

方法的行为与方法略有不同;该方法使用严格的相等比较来比较值,而严格的相等比较不考虑等于它本身。.includes().indexOf().indexOf()NaN

console.log([NaN].indexOf(NaN));

有关不同相等性检查算法的信息可以在MDN上找到:

MDN - 平等比较和同一性