Answers:
tl; dr: NaN
区别对待:
[NaN].indexOf(NaN) > -1
是 false
[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比较算法而不是严格相等比较之外,这与上面的语义几乎相同,因此是
[NaN].includes(NaN)
正确的。因此,该建议解决了现有代码中出现的两个问题。
为了一致性
fromIndex
,我们还添加了一个类似于Array.prototype.indexOf
和的参数String.prototype.includes
。
更多信息:
undefined
通过.includes()
,并且不审议.indexOf()
。
.indexOf()
和.includes()
方法可用于搜索数组中的元素或搜索给定字符串中的字符/子字符串。
(链接到ECMAScript规范)
indexOf
使用严格平等比较,而includes
使用SameValueZero算法。因此,出现以下两点差异。
正如Felix Kling所指出的,行为是不同的NaN
。
let arr = [NaN];
arr.indexOf(NaN); // returns -1; meaning NaN is not present
arr.includes(NaN); // returns true
undefined
。let arr = [ , , ];
arr.indexOf(undefined); // returns -1; meaning undefined is not present
arr.includes(undefined); // returns true
(链接到ECMAScript规范)
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
正如538ROMEO所指出的那样,它includes
可能会慢一点(非常小)(因为它需要检查正则表达式作为第一个参数),indexOf
但实际上,这并没有太大的区别,可以忽略不计。
String.prototype.includes()
是在ECMAScript 2015 Array.prototype.includes()
中引入的,而在ECMAScript 2016中引入的。关于浏览器支持,请明智地使用它们。
String.prototype.indexOf()
并且Array.prototype.indexOf()
存在于ECMAScript的ES5版中,因此受所有浏览器支持。
indexOf
true
在明确设置undefined
为数组后给出:let arr=[undefined];
或let arr=[];arr[0]=undefined;
现在arr.indexOf(undefined) === 0
undefined
:原因是.includes
将缺少的元素视为undefined
,而.indexOf()
忽略了它们。您也可以使用来“创建”缺少的元素arr[number beyond length] = whatever
。
.includes()
只吃琴弦。实际上,这两种方法都尽可能将任何内容强制转换为字符串。正则表达式被明确排除在考虑范围之外,.includes()
以允许根据当前草案在将来对标准进行添加。
从概念上讲,当您要使用位置indexOf时,应仅使用indexOf来提取值或对数组进行操作,即在获取元素位置后使用切片,移位或分割。另一方面,使用Array.includes仅知道值是否在数组内,而不是位置,因为您不在乎它。
indexOf()
并且includes()
都可以用于查找数组中的元素,但是每个函数产生不同的返回值。
indexOf
返回一个数字(-1
如果元素不存在于数组中,或者返回数组位置,如果存在该元素)。
includes()
返回一个布尔值(true
或false
)。
includes
对浏览器的支持要差得多。