includes()能正确识别NaN,因其内部使用SameValueZero算法使NaN===NaN为true;而===和indexOf()均无法做到,故[NaN].includes(NaN)返回true,[NaN].indexOf(NaN)返回-1。

直接用 includes() 就行,它原生支持 NaN 判定,无需额外处理。
为什么 includes() 能正确识别 NaN
includes() 内部使用 SameValueZero 算法,该算法规定 NaN === NaN 为 true;而原生 === 和 indexOf() 都做不到这一点。
-
[NaN].includes(NaN)→ true -
[NaN].indexOf(NaN)→ -1 -
NaN === NaN→ false
实际使用时的写法示例
只要数组中存在 NaN,无论位置在哪,includes() 都能准确返回 true:
-
[1, 2, NaN, 4].includes(NaN)→ true -
[undefined, null, 'a'].includes(NaN)→ false -
[0, -0, NaN].includes(NaN)→ true
注意事项与常见误区
虽然 includes 对 NaN 友好,但要注意这些边界情况:
- 它只检测数组**显式存入的 NaN**,不会把空槽位(empty slot)当作 NaN
- 不要混淆:
Number.isNaN(x)用于判断某个值是否为 NaN,而arr.includes(NaN)是判断 NaN 是否在数组里 - 避免误写成
arr.includes('NaN')—— 字符串 'NaN' 和原始值 NaN 完全不同
对比其他方法:为什么不用 indexOf 或 findIndex
传统方式容易出错,语义也不清晰:
-
arr.indexOf(NaN) !== -1❌ 总是 false,不可靠 -
arr.findIndex(x => x !== x)✅ 可行(利用 NaN ≠ NaN),但可读性差、逻辑绕 -
arr.some(Number.isNaN)✅ 也可用,但仅适用于检查元素本身是否为 NaN,不能指定查找目标










