Array.prototype.includes 对比 Array.prototype.indexOf

Array.prototype.includes vs. Array.prototype.indexOf

除了提高可读性之外,includesindexOf 相比还有什么优势吗?他们看起来和我一模一样。

这有什么区别

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

还有这个?

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

tl;dr: NaN 区别对待:

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

来自proposal

Motivation

When using ECMAScript arrays, it is commonly desired to determine if the array includes an element. The prevailing pattern for this is

if (arr.indexOf(el) !== -1) {
    ...
}

with various other possibilities, e.g. arr.indexOf(el) >= 0, or even ~arr.indexOf(el).

These patterns exhibit two problems:

  • They fail to "say what you mean": instead of asking about whether the array includes an element, you ask what the index of the first occurrence of that element in the array is, and then compare it or bit-twiddle it, to determine the answer to your actual question.
  • They fail for NaN, as indexOf uses Strict Equality Comparison and thus [NaN].indexOf(NaN) === -1.

Proposed Solution

We propose the addition of an Array.prototype.includes method, such that the above patterns can be rewritten as

if (arr.includes(el)) {
    ...
}

This has almost the same semantics as the above, except that it uses the SameValueZero comparison algorithm instead of Strict Equality Comparison, thus making [NaN].includes(NaN) true.

Thus, this proposal solves both problems seen in existing code.

We additionally add a fromIndex parameter, similar to Array.prototype.indexOf and String.prototype.includes, for consistency.


更多信息:

技术上

使用 indexOf

时,

NaN 无法找到

[NaN].indexOf(NaN) // => -1 (not found)
[NaN].includes(NaN) // => true

includes 也没有用 如果您想知道在何处找到该元素.

可读性

arr.indexOf('blah') !== -1 可读性和可维护性更少。另一方面,arr.includes('blah') 照它说的做,很明显它 returns a boolean.

表演

根据 this article 关于这个主题 没有明显的区别 虽然 includes 可能会慢一点。

历史

indexOf 是在 includes.

之前创建的

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

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

数组中的用法

Link ECMAScript 规范)

  1. indexOf 使用 Strict Equality Comparison whereas includes uses the 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

字符串中的用法

Link ECMAScript 规范)

1。 如果您将 RegExp 传递给 indexOf,它将把 RegExp 视为一个字符串,并且如果找到,则 return 字符串的索引。但是,如果您将 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 2015 中引入的,而 Array.prototype.includes() 是在 ECMAScript 2016 中引入的。关于浏览器支持,请明智地使用它们。

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

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

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

includes() returns 一个布尔值(truefalse)。

Internet Explorer 不支持包含,如果这有助于您决定的话。

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/includes#Browser_compatibility

indexOf 是检查数组中是否有内容的旧方法,新方法更好,因为您不必为 (-1) 编写条件,所以这就是使用 include() 的原因returns 你是布尔值的方法。

array.indexOf('something')      // return index or -1
array.includes('something')     // return true of false

所以对于查找索引,第一种方法更好,但对于检查存在与否,第二种方法更有用。

答案和例子都很棒。但是(乍一看),这让我误解了 includes 在使用 undefined.

时总是 return true

因此,我包括示例以详细说明 includes 可用于检查未定义和 NaN 值 wherelse indexOf can't

//Array without undefined values and without NaN values. 
//includes will return false because there are no NaN and undefined values

const myarray = [1,2,3,4]

console.log(myarray.includes(undefined)) //returns false
console.log(myarray.includes(NaN)) //returns false


//Array with undefined values and Nan values.
//includes will find them and return true

const myarray2 = [1,NaN, ,4]

console.log(myarray2.includes(undefined)) //returns true
console.log(myarray2.includes(NaN)) //returns true


console.log(myarray2.indexOf(undefined) > -1) //returns false
console.log(myarray2.indexOf(NaN) > -1) //returns false

总结

  • includes 可以用于检查数组
  • 中的未定义和NaN值
  • indexOf 不能用于检查数组
  • 中的未定义和NaN值

includes 使用自动类型转换,即在字符串和数字之间。 indexOf 没有。

 
let allGroceries = ['tomato', 'baked bean',];
 
//returns true or false
console.log(allGroceries.includes("tomato")); //uses boolean value to check 

let fruits2 = ["apple", "banana", "orange"];
console.log(fruits2.includes("banana"));
// returns true because banana is in the array



//.indexOf returns the index of the value

console.log(allGroceries.indexOf("tomato"));//returns the index of the value
//returns -1 because tomato is not in the array
//fromIndex
console.log(allGroceries.indexOf("tomato", 2));


includes() 方法与 indexOf() 略有不同 一种重要的方法。 indexOf() 使用 与 === 运算符相同的算法,以及相等算法 认为 not-a-number 值与其他值不同 价值,包括它本身。 includes() 使用了一个稍微不同的版本 确实认为 NaN 等于自身的相等性。这意味着 indexOf() 不会检测数组中的 NaN 值,但是 包括()将:

let a = [1,true,3,NaN];
a.includes(NaN) // => true
a.indexOf(NaN) // => -1; indexOf can't find NaN

来自JavaScript: The Definitive Guide by David Flanagan