includes()能正确识别nan而indexof()不能,因前者用samevaluezero算法(nan与自身相等),后者用严格相等(nan===nan为false);同理适用于+0/-0及稀疏数组空槽位。

识别 includes() 与 indexOf() 在处理 NaN 时的差异,关键在于理解它们底层使用的相等算法不同——不是写法问题,而是语言规范决定的行为。
核心区别:用什么规则判断“相等”
indexOf() 使用严格相等(===),而 includes() 使用 SameValueZero 算法:
-
NaN === NaN永远是false→ 所以[NaN].indexOf(NaN)返回-1 -
SameValueZero(NaN, NaN)规定为true→ 所以[NaN].includes(NaN)返回true - 这个差异也影响
+0和-0:includes(+0)与includes(-0)都返回true;indexOf()同样能匹配两者,但不区分它们
实际测试一眼看穿
直接运行这几行代码就能验证:
const arr = [1, NaN, 2, -0];<br>console.log(arr.includes(NaN)); // true<br>console.log(arr.indexOf(NaN)); // -1<br>console.log(arr.includes(-0)); // true<br>console.log(arr.indexOf(-0)); // 3
只要结果对 NaN 出现“一个返回 true、一个返回 -1”,就说明你已识别出该差异。
别被表面逻辑带偏
有人误以为“加个判断就能让 indexOf 支持 NaN”,其实不行:
-
arr.indexOf(NaN)不可能返回有效索引,这是它的固有行为,无法通过参数或技巧绕过 - 手动遍历 +
Number.isNaN()是补救手段,不是indexOf本身变聪明了 - 如果业务频繁需要检测
NaN是否存在,说明该用includes(),而不是硬套indexOf
延伸提示:空槽位(empty slot)也体现差异
对稀疏数组中未赋值的位置(如 new Array(3)),includes() 将其视为 undefined 并能匹配:
-
const a = new Array(3); a.includes(undefined)→true -
a.indexOf(undefined)→-1(它不把空槽当undefined)
这进一步印证:二者不是“功能相似只差返回值”,而是判定逻辑根本不同。










