es2016 - Array.prototype.includes()
阶段:stage4, Finished
参考:
动机
当使用数组的时候,经常会需要判断数组中是否包含某个元素,然后经常使用如下用法:
if (arr.indexOf(el) !== -1) {}
arr.indexOf(el) >= 0;
~arr.indexOf(el)
上述用法会存在两个问题:
- 用法含义不够清晰(fail to "say what you mean"):上述方法是判断数组中第一个匹配上该元素的位置,用这种方式来决定你想问的问题:是否包含该元素
[NaN].indexOf(NaN) === -1,所以对NaN是无效的。
解决方案
因此提议了一个Array.prototype.includes方法,使得上述代码可以写成
if (arr.includes(el)) {
...
}
这样的用法,含义就比较的清晰了。includes使用了零值相等的比较方式,使得NaN可以等于NaN。
includes方法解决存在的问题,并且提供一个可选的fromIndex参数,与Array.prototype.indexOf 和String.prototype.includes方法保持统一。
如何使用Array.prototype.includes()方法
arr.includes(valueToFind[, fromIndex])
Array.prototype.includes()方法接受两个参数:要搜索的值及开始搜索的索引位置,第二个参数是可选的。提供第二个参数时,includes()将从索引开始匹配(默认的开始索引位置为0)。如果在数组中找到要搜索的值,返回true,否则返回false。
let values = [1,2,3];
console.log(values.includes(1)); // true
console.log(values.includes(0)); // false
// 从3开始搜查
console.log(values.includes(1, 2)); // false
值的比较
用includes()方法进行值比较的时候,=操作符的使用有一个例外:即使NaN === NaN的计算结果为false,NaN也被认为是等于NaN,这与indexOf()方法的行为不同,或者严格使用=进行比较。
let values = [1, NaN, 2];
console.log(values.indexOf(NaN)); // -1
console.log(values.includes(NaN)); // true
还有个奇怪之处,+0与-0被认为是相等的。在这种情况下,indexOf()和includes()的表现行为一致:
let values = [1, +0, 2];
console.log(values.indexOf(-0)); // 1
console.log(values.includes(-0)); // true
Includes uses the SameValueZero comparision algorithm instead of Strict Equalify Comparison, thus make [NaN].includes(NaN) true.
FAQ
why includes instead of has ?
如果调查现有的各种API。会发现has方法在概念上用于搜索keys,includes用于搜索值。
- Keys inside a key-value map:
Map.prototype.has(key),WeakMap.prototype.has(key),Reflect.has(target, propertyKey) - Sets, whose elements are conceptually both keys and values:
Set.prototype.has(value),WeakSet.prototype.has(value),Reflect.Loader.prototype.has(name) - 字符串,在概念上是从索引到代码点的映射:
String.prototype.includes(searchString, position)
从统一性来说,最好的就是和String方法保持一致,而不是Map或Set。
But String.prototype.includes works on strings, not characters!?
yes, that's true.
浙公网安备 33010602011771号