Array数组的indexOf、includes vs for-loop性能比较
最近遇到一道算法题,然后有些人会使用 includes、indexOf 去判断是否存在另一个数。这让我不禁思考,这和 for loop有什么区别,能减少时间复杂度吗?我一开始也不是很清楚,但我可以找文档,找标准。我的第一判断是 includes 完全和 for loop没有区别的,只是es6 标准规范提供的语法糖,而 indexOf 还是有一定效率的。带着疑惑,查看 MDN 和 ecma-262
includes
includes 是 ES6 新增语法,返回 布尔值。最容易拿 indexOf 来比较, indexOf 不能判断 NaN, 而且不够语义,返回的是 匹配值的位置 或 -1。
includes 内部实现是这样的:
- Let O be ? ToObject(this value).
- Let len be ? ToLength(? Get(O, “length”)).
- If len is 0, return false.
- Let n be ? ToInteger(fromIndex). (If fromIndex is undefined, this step produces the value 0.)
- If n ≥ 0, then
- Let k be n.
- Else n < 0,
- Let k be len + n.
- If k < 0, let k be 0.
- Repeat, while k < len
- Let elementK be the result of ? Get(O, ! ToString(k)).
- If SameValueZero(searchElement, elementK) is true, return true.
- Increase k by 1.
- Return false.
其中的 SameValueZero 内部实现是这样的:
- If Type(x) is different from Type(y), return false.
- If Type(x) is Number, then
- If x is NaN and y is NaN, return true.
- If x is +0 and y is -0, return true.
- If x is -0 and y is +0, return true.
- If x is the same Number value as y, return true.
- Return false.
- Return SameValueNonNumber(x, y).
从上面可以看出 includes 内部是使用 while 循环,并不能够降低时间复杂度。它能判断出 NaN 以及 +0等于-0。
所以,返回值的语义化和 NaN的判断就是 includes 的场景。
indexOf
好,includes 用来提升效率的幻想破灭了,那 indexOf 呢,规范是这么写的:
- Let O be ? ToObject(this value).
- Let len be ? ToLength(? Get(O, “length”)).
- If len is 0, return -1.
- Let n be ? ToInteger(fromIndex). (If fromIndex is undefined, this step produces the value 0.)
- If n ≥ len, return -1.
- If n ≥ 0, then
- If n is -0, let k be +0; else let k be n.
- Else n < 0,
- Let k be len + n.
- If k < 0, let k be 0.
- Repeat, while k < len
- Let kPresent be ? HasProperty(O, ! ToString(k)).
- If kPresent is true, then
- Let elementK be ? Get(O, ! ToString(k)).
- Let same be the result of performing Strict Equality Comparison searchElement === elementK.
- If same is true, return k.
- Increase k by 1.
- Return -1.
Array的 indexOf 也使用了 while 循环,并使用 === 全等比较。(注: 与 String.prototype.indexOf 并不同)
indexOf 使用场景是需要知道 匹配值的位置。
结论
这是一个性能测试比较

so? 如果单纯只是想比较,简单的才是最快的。 includes与indexOf效率相当,而for Loop最快,因为没有其他的前置判断和浏览器对它的优化。