Array.prototype.includes 与 Array.prototype.indexOf

IT技术 javascript ecmascript-2016
2021-01-24 13:32:42

除了提高可读性之外,includesover有什么优势indexOf吗?他们在我看来是一样的。

这有什么区别

var x = [1,2,3].indexOf(1) > -1; //true

还有这个?

var y = [1,2,3].includes(1); //true
6个回答

tl;dr: NaN区别对待:

  • [NaN].indexOf(NaN) > -1false
  • [NaN].includes(NaN)true

提案

动机

使用 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 比较算法而不是 Strict Equality Comparison ,从而使[NaN].includes(NaN)true 。

因此,该提议解决了在现有代码中看到的两个问题。

为了一致性fromIndex我们还添加了一个类似于Array.prototype.indexOf参数String.prototype.includes


更多信息:

只说对了一半。同样不同的是:缺少的元素被视为undefined.includes(),而不是由 考虑.indexOf()
2021-03-14 13:32:42

从技术上讲,唯一的区别是处理方式NaNundefined方式使用时无法找到它们indexOf

arr.indexOf('blah') !== -1少可读性和可维护性另一方面,按照arr.includes('blah')它所说的去做,很明显它返回一个boolean.

includes如果您想知道字符串在数组中的位置,也没有用

关于性能:根据这篇关于该主题的文章虽然可能会慢一点,没有明显差异includes

indexOf之前创建的方式includes

似乎性能差异并不那么明显。我的移动 Firefox 显示 indexOf 实际上更快。一些 Chrome 版本的行为相同......但无论如何在今天的实现中差异似乎可以忽略不计。
2021-03-18 13:32:42
刚刚打开一个控制台并对其进行了测试:let allElements = [...document.getElementsByTagName('*')]; let t1 = performance.now(); for(let i=0;i<1e7;i++){ randEl = allElements[Math.floor(Math.random()*allElements.length)]; const isIn = allElements.includes(randEl); } let t2 = performance.now(); for(let i=0;i<1e7;i++){ randEl = allElements[Math.floor(Math.random()*allElements.length)]; const isIn = (allElements.indexOf(randEl)>-1); } let t3 = performance.now(); console.log('Include time:', t2-t1); console.log('indexOd time:', t3-t2);结果:包括速度提高了 40 倍。
2021-03-24 13:32:42

.indexOf().includes()方法可用于搜索数组中的元素或搜索给定字符串中的字符/子字符串。

数组中的用法

链接到 ECMAScript 规范)

  1. indexOf使用严格相等比较includes使用SameValueZero算法。由于这个原因,出现了以下两点差异。

  2. 正如Felix Kling所指出的,在 的情况下,行为是不同的NaN

let arr = [NaN];

arr.indexOf(NaN); // returns -1; meaning NaN is not present
arr.includes(NaN); // returns true
  1. 在 的情况下,行为也不同undefined
let arr = [ , , ];

arr.indexOf(undefined); // returns -1; meaning undefined is not present
arr.includes(undefined); // returns true

字符串中的用法

链接到 ECMAScript 规范)

1. 如果您将 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

表现

正如GLAND_PROPRE指出的那样,includes可能比(因为它需要检查正则表达式作为第一个参数)慢一点(非常小),indexOf但实际上,这没有太大区别,可以忽略不计。

历史

String.prototype.includes()在 ECMAScript 2015Array.prototype.includes()中引入,在 ECMAScript 2016 中引入。关于浏览器支持,请明智地使用它们。

String.prototype.indexOf()并且Array.prototype.indexOf()出现在 ECMAScript 的 ES5 版本中,因此被所有浏览器支持。

indexOftrue显式设置undefined为数组给出let arr=[undefined];let arr=[];arr[0]=undefined;现在arr.indexOf(undefined) === 0
2021-03-15 13:32:42
没有人要求字符串,但您的评论表明.includes()只吃字符串。实际上,这两种方法都尽可能地将任何内容强制转换为字符串。正则表达式是特别排除作为参数.includes(),以允许将来增加的标准根据当前草案。
2021-03-22 13:32:42
你是唯一一个指出与 不同的人undefined:原因是.includes将缺失的元素视为undefined,而.indexOf()忽略它们。您还可以“创建”缺少的元素arr[number beyond length] = whatever
2021-03-30 13:32:42

从概念上讲,当您想使用 indexOf 位置时,您应该使用 indexOf 只是让您提取值或对数组进行操作,即在获得元素位置后使用切片、移位或拆分。另一方面,使用 Array.includes 只知道值是否在数组内而不是位置,因为您不关心它。

如果您想支持旧浏览器,请使用 indexOf,这通常是一个好主意。如果您的代码不会在浏览器中执行,请使用包含,因此您知道您不需要支持像 IE 这样的旧浏览器,我向您保证人们仍在使用。如果您需要测试 NaN 或 undefined 等值并且仍希望支持旧浏览器,请不要使用。只需使用老式的 for 循环即可。对于那些不知道 IE 不是现代浏览器或没有任何选择的人来说,编写 for 循环和支持 IE 并没有什么可耻的,因为他们在公共/工作计算机上。
2021-04-09 13:32:42

indexOf()includes()都可以用于查找数组中的元素,但是每个函数产生不同的返回值。

indexOf返回一个数字(-1如果元素不存在于数组中,或者如果元素存在则返回数组位置)。

includes()返回一个布尔值(truefalse)。

嗨 Kruti,这个问题已经得到了回答,并且有一个公认的答案。此外,您可以看到您的答案如何仅包含其他答案中已经说过的信息。说到底,这个问题已经有 4 年的历史了。请提供有关最新问题或未回答问题的指导。谢谢
2021-03-31 13:32:42