includes() 支持 NaN,因用 SameValueZero 比较;indexOf() 不支持,因用 === 比较,NaN === NaN 恒为 false,故 [NaN].includes(NaN) 返回 true,[NaN].indexOf(NaN) 返回 -1。
识别 includes() 与 indexof() 在处理 nan 时的差异,关键在于理解它们底层使用的比较算法不同:前者用 samevaluezero,后者用严格相等(===)。
NaN 比较结果截然相反
NaN === NaN 恒为 false,这是 JavaScript 的语言规范。因此:
-
[NaN].indexOf(NaN)返回-1(表示“没找到”) -
[NaN].includes(NaN)返回true(明确表示“存在”)
行为差异不只限于 NaN
SameValueZero 还统一处理了 +0 和 -0:
-
[+0].includes(-0)→true -
[+0].indexOf(-0)→0(也返回索引,但语义上仍是“找到了”)
也就是说,对 0 相关值两者表现一致;真正拉开差距的,就是 NaN。
实际判断场景中的影响
当你写条件逻辑来检测数组是否含某个值时:
- 用
arr.indexOf(x) !== -1:若x是NaN,永远为false,逻辑失效 - 用
arr.includes(x):天然支持NaN,结果符合直觉
例如:[1, NaN, 3].includes(NaN) ✅ 返回 true;而 [1, NaN, 3].indexOf(NaN) > -1 ❌ 实际计算为 -1 > -1,即 false。
替代方案需额外处理
如果不用 includes(),又必须支持 NaN,就得手动补逻辑:
- 用
some()配合Number.isNaN()或Object.is() - 例如:
arr.some(item => Object.is(item, NaN)) - 但这样写更冗长,且无法复用原生数组方法的简洁性

















