Javascript Array.prototype.includes与Array.prototype.indexOf
除了提高可读性之外,Javascript Array.prototype.includes与Array.prototype.indexOf,javascript,ecmascript-2016,Javascript,Ecmascript 2016,除了提高可读性之外,includes是否比indexOf有任何优势?对我来说,他们似乎一模一样 这两者有什么区别 var x = [1,2,3].indexOf(1) > -1; //true 这个呢 var y = [1,2,3].includes(1); //true tl;dr:NaN受到不同的对待: [NaN].indexOf(NaN)>-1为false [NaN]。包括(NaN)为真 从: 动机 使用ECMAScript数组时,通常需要确定数组是否包含元素。这方面的主流
includes
是否比indexOf
有任何优势?对我来说,他们似乎一模一样
这两者有什么区别
var x = [1,2,3].indexOf(1) > -1; //true
这个呢
var y = [1,2,3].includes(1); //true
tl;dr:
NaN
受到不同的对待:
为[NaN].indexOf(NaN)>-1
false
为[NaN]。包括(NaN)
真
从: 动机 使用ECMAScript数组时,通常需要确定数组是否包含元素。这方面的主流模式是
if (arr.indexOf(el) !== -1) {
...
}
具有各种其他可能性,例如arr.indexOf(el)>=0
,甚至~arr.indexOf(el)
这些模式表现出两个问题:
- 他们没有“说出你的意思”:你不是询问数组是否包含元素,而是询问数组中该元素第一次出现的索引是什么,然后比较它或稍微旋转它,以确定实际问题的答案
- 它们在
中失败,因为NaN
使用严格的相等比较,因此indexOf
[NaN]。indexOf(NaN)==-1
Array.prototype.includes
方法,这样上面的模式就可以重写为
if (arr.includes(el)) {
...
}
除了使用SameValueZero比较算法而不是严格的相等比较外,它的语义与上面的几乎相同,从而使[NaN].includes(NaN)
为真
因此,这个建议解决了现有代码中的两个问题
为了保持一致性,我们还添加了一个fromIndex
参数,类似于Array.prototype.indexOf
和String.prototype.includes
进一步资料:
NaN
和未定义的。当使用索引of
时,它们将无法找到
arr.indexOf('blah')!=-1
的可读性和可维护性较低。另一方面,arr.includes('blah')
执行它所说的操作,显然它返回一个布尔值
如果您想知道字符串在数组中的位置,includes
也没有用
关于性能:根据主题没有明显的差异,尽管包括
可能会稍微慢一点
indexOf
是在includes
之前创建的indexOf从概念上讲,当您想使用位置indexOf时,您应该使用indexOf,即在获得元素位置后使用slice、shift或split来提取值或对数组进行操作。另一方面,使用Array.includes只能知道值是否在数组中,而不是位置,因为您不关心它。.indexOf()
和.includes()
方法可用于搜索数组中的元素或搜索给定字符串中的字符/子字符串
数组中的用法
(根据ECMAScript规范)
indexOf
使用算法,而includes
使用算法。由于这个原因,出现了以下两点差异
正如所指出的,在NaN
的情况下,行为是不同的
如果未定义
,行为也不同
字符串用法
(根据ECMAScript规范)
一,。
如果将RegExp传递给indexOf
,它会将RegExp视为字符串,并返回字符串的索引(如果找到)。但是,如果将RegExp传递给includes
,它将抛出异常
let str = "javascript";
str.indexOf(/\w/); // returns -1 even though the elements match the regex because /\w/ is treated as string
str.includes(/\w/); // throws TypeError: First argument to String.prototype.includes must not be a regular expression
演出
正如所指出的,includes
可能比indexOf
慢一点(非常小),因为它需要检查正则表达式作为第一个参数),但实际上,这没有多大区别,可以忽略不计
历史
ECMAScript 2015中引入了String.prototype.includes()
,而ECMAScript 2016中引入了Array.prototype.includes()。关于浏览器支持,请明智地使用它们
String.prototype.indexOf()
和Array.prototype.indexOf()
出现在ECMAScript的ES5版本中,因此受到所有浏览器的支持。indexOf()
和includes()
都可以用于查找数组中的元素,但是每个函数都会产生不同的返回值
indexOf
返回一个数字(-1
如果元素不在数组中,或者如果元素存在,则返回数组位置)
includes()
返回一个布尔值(true
或false
)。Internet explorer不支持includes,如果这有助于您决定
indexOf是检查数组中是否有内容的旧方法,新方法更好,因为您不必为存在(-1)编写条件,这就是为什么要使用返回布尔值的include()方法
array.indexOf('something') // return index or -1
array.includes('something') // return true of false
因此,对于查找索引,第一种方法更好,但对于检查是否存在,第二种方法更有用。includes
的浏览器支持更差。请注意,includes
不是ES6/ES2015的一部分。这是ECMAScript下一个版本的提案,将于今年添加。我还想指出的是,IE中根本不支持includes
,includes
大约比indexOf慢50倍,至少在Chrome中是这样。当心@你有什么可以证明这一点的吗?看起来性能上的差异并不是那么明显。我的移动Firefox显示indexOf实际上更快。
let str = "javascript";
str.indexOf(/\w/); // returns -1 even though the elements match the regex because /\w/ is treated as string
str.includes(/\w/); // throws TypeError: First argument to String.prototype.includes must not be a regular expression
array.indexOf('something') // return index or -1
array.includes('something') // return true of false