• 作者:老汪软件技巧
  • 发表时间:2024-10-13 00:01
  • 浏览量:

背景

事情的起因是我看到 AI 回复了这句话:includes() 方法使用 === 进行判断,但它与 indexOf() 方法不同,因为 includes() 方法能够正确处理 NaN,而 indexOf() 不能。

indexOf 与 includes 居然还有这么细微的差别,我比较好奇原因,想到了可以去 ES 规范 一探究竟

原因

搜索 indexOf 与 includes 发现他们使用了不同的比较算法:

This method compares searchElement to the elements of the array, in ascending order, using the IsStrictlyEqual algorithm, and if found at one or more indices, returns the smallest such index; otherwise, it returns -1.

这里使用了 算法

This method compares searchElement to the elements of the array, in ascending order, using the SameValueZero algorithm, and if found at any position, returns true; otherwise, it returns false.

这里使用了 算法,他们使用的比较算法是不同的所以造成了这种差异

总结

上也有相关介绍。

使用 AI 时,如果提示从 ES 规范方面比较,他也是能回答出来的,不得不说,只有提示词写的合适,AI 是真的强大。(我使用的 Kimi)

AI 回答的重点:

indexOf 使用严格相等比较(===)来查找元素,这意味着它不能正确处理 NaN。在 JavaScript 中,NaN 是一个特殊的值,它与任何值都不相等,包括它自己(NaN === NaN 返回 false)。因此,当使用 indexOf 搜索 NaN 时,即使数组中存在 NaN,也会返回 -1。

includes 方法的实现细节可以参考 ECMAScript 7 实现规范,它内部采用了 SameValueZero 实现,这使得 includes 不区分 +0 和 -0,并且能够检测到 NaN。

只是这么两个常用的 api 就有这样的细节,所以学习技术还是应该有必要深入原理了解的。

附录IsStrictlyEqual 算法解释

IsStrictlyEqual 是 ECMAScript 语言规范中定义的一个抽象操作,它用于比较两个值是否严格相等,这与 === 运算符的语义是一致的。下面是这个操作的具体步骤和解释:

类型比较:首先,它会检查两个值 x 和 y 是否属于相同的类型。如果它们的类型不同(即 SameType(x, y) 返回 false),那么 IsStrictlyEqual 将立即返回 false。这意味着不同类型的值永远不会被认为是严格相等的。

数值比较:

非数值比较:如果 x 不是数值类型,那么算法将调用 SameValueNonNumber(x, y) 方法。这个方法会进行更细致的比较,包括:

SameValueZero 算法解释

他与上面流程基本一致,不同点在于 IsStrictlyEqual 调用 调用 方法比较,而 SameValueZero 调用 来比较,Number::equal 如果是 NaN 就直接返回 false 了,Number::sameValueZero 如果两个都是 NaN 就返回 true。