An old dog learns code

array.indexOf和array.includes

October 03, 2018


一点微小差别

indexOf 和 includes 都可以用来判断数组是否包含某个元素,二者到底有什么区别呢?看一个例子:

let a = [1,2,3,null,undefined,NaN];

if(a.indexOf(NaN)!==-1){
  console.log('using Array.indexOf: Found NaN in Array a!');
}else{
  console.log('using Array.indexOf: No NaN found in Array a~');
}

if(a.includes(NaN)){
  console.log('using Array.includes: Found NaN in Array a!');
}else{
  console.log('using Array.includes: No NaN found in Array a~');
}

//输出:
>'using Array.indexOf: No NaN found in Array a~'
>'using Array.includes: Found NaN in Array a!'

为什么

二者内部使用的算法不同:

  • indexof 内部使用全等操作符,即===进行比较;
  • includes 内部使用的算法是SameValueZero

全等操作符进行NaN===NaN比较时,必然返回false,所以indexOf无法判断数组内是否含有 NaN。

SameValueZero规则 2.1解释了原因:

  1. x,y类型不同,返回false
  2. x,y同为number类型,那么

    1. 同为NaN时,返回true
    2. 同为 0 时(不管 0 之前的符号),返回true
    3. 数值相等时,返回true
    4. 其他情况,返回false
  3. x,y同为其他类型,仅在值相同时返回true

结论

其实indexOfincludes二者的搜索机制差不多,只有比较算法不同。实际使用我倾向于后者,一方面因为前者这个隐含的坑,另一方面后者直接返回true/false,更加直观。

参考文献