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