JS判断数组是否包含某元素

我在学习ES6数组拓展时,发现了新增了很多了有趣的数组方法,忽然想好工做中判断数组是否包含某个元素是很是常见的操做,那么这篇文章顺便作个整理。数组

1.for循环结合break浏览器

可能不少人第一会想到for循环,毕竟for是最为保险和熟悉的操做:函数

let arr = [1, 2, undefined, '听风是风', 'echo'],
    i = 0;
const LENGTH = arr.length;

//初始化result状态,只要能找到匹配的则修改成true
let result = false;
for (; i < LENGTH; i++) {
    if (arr[i] === '听风是风') {
        result = true;
        break;
    };
};
if (result) {
    //do something...
};

使用for的好处是,能结合break在找到知足条件的状况下,马上跳出循环,若是第一个元素就符合条件,那后续循环步骤均可以优化直接跳过了。学习

使用for的缺点是,查找不够直观,咱们在for循环中没法直接return查询结果,固然你能够将for循环写在一个函数中,但你仍是须要额外定义个result变量。优化

其次,对于数组操做,咱们虽然能使用for循环解决不少问题,但咱们不能把目光永远第一个投向for,除了for呢?试着将目光投向更多数组高阶函数,思考更多多是很是必要的。spa

说到for你确定会本能想到forEach,虽然forEach能使用回调函数,但依旧没法在回调函数中使用return,外加上没法直接使用break,这里就不作介绍了。prototype

最后,for循环与forEach对于查找NaN不那么实用,毕竟NaN是惟一一个不等于本身的存在,固然也能实现又能判断NaN还能判断其它非NaN对象,只是比较麻烦了。code

2.Arr.indexOf()方法对象

let arr = [1, 2, undefined, '听风是风', 'echo'];

//利用indexOf查找下标的特性
let result = arr.indexOf('听风是风');//3
if (result>-1) {
    //do something...
};

indexOf方法会从头至尾的检索数组,若是找到了第一个符合条件的元素则返回该元素的下标,若是没找到则返回-1,因此只要能找到最小下标也应该是0,这才有了if(result>-1)的写法。blog

相对for循环来讲,indexOf写法上简洁了很多,但相比for循环能使用break,indexOf即使找到了想要的元素,它仍是不会停下检索的脚步,这点就不太优化了。

其次,语义化不太友好,咱们是但愿判断一个数组有没有某个元素,结果咱们究竟是拿了下标来作判断,固然,对于NaN查找也不那么友好。

[NaN].indexOf(NaN);//-1

2.find()与findIndex()方法

let arr = [1, 2, undefined, '听风是风', 'echo'];

//利用indexOf查找下标的特性
let result = arr.find(ele => ele === '听风是风')//听风之风
if (result) {
    //do something...
};

find方法是比较推荐的作法,find方法会找到第一个符合条件的数组元素,并返回它,若是没找到则返回undefined。

须要注意的是,只要find找到符合条件的对象后不会继续遍历,能够说自带了break操做,加上箭头函数简化回调,总体代码很是直观。

let arr = [1, 2, undefined, '听风是风', 'echo'];

//利用indexOf查找下标的特性
let result = arr.findIndex(ele => ele === '听风是风')//3
if (result>-1) {
    //do something...
};

findIndex方法与find方法很是相似,只是它返回的不是符合条件的对象,而是该对象的下标,找到后一样会跳出循环,若是没找到则返回-1,这一点与indexOf有点相似。

比较理想的是,find方法还能结合Object.is()方法判断NaN,固然也能判断其它对象,是否是很是的奈斯?

[NaN].find(ele => Object.is(NaN, ele)); //NaN
[1].find(ele => Object.is(1, ele)); //1
[NaN].findIndex(ele => Object.is(NaN, ele)); //0
[1].findIndex(ele => Object.is(1, ele)); //0

写法简洁,自带break,还能判断NaN,这两个方法都比较推荐。

3.some()方法

let arr = [1, 2, undefined, '听风是风', 'echo'];

//利用indexOf查找下标的特性
let result = arr.some(ele => ele === '听风是风') //true
if (result) {
    //do something...
};

some方法一样用于检测是否有知足条件的元素,若是有,则不继续检索后面的元素,直接返回true,若是都不符合,则返回一个false。

用法与find类似,只是find是返回知足条件的元素,some返回的是一个Boolean值,从语义化来讲,是否包含返回布尔值更贴切。

固然,some方法一样能结合Object.is()方法检测NaN。some也是较为推荐的方法

[NaN].some(ele => Object.is(NaN, ele));

4.includes()方法

ES6新增的数组方法,用于检测数组是否包含某个元素,若是包含返回true,不然返回false,比较厉害的是,能直接检测NaN

[1, 3, 'echo'].includes('echo'); //true
[NaN, 3, 'echo'].includes(NaN); //true
[1, 3, 'echo'].includes('听风是风'); //false

优势就不用说了,最简单的作法没有之一,不用回调,不用复杂的写法,一个方法直接搞定。

缺点是低版本浏览器支持不是很友好,固然能用咱们仍是用,不能用咱们就本身封装:

let hasEle = (() =>
    Array.prototype.includes ?
    (arr, val) => arr.includes(val) :
    (arr, val) => arr.some(ele => Object.is(val, ele))
)();

hasEle([1, 2, NaN], 1) //true
hasEle([1, 2, NaN], NaN) //true
hasEle([1, 2, NaN], '听风是风') //false

但愿到这里,在之后查找某数组是否包含某元素时,你又多了几种新的花样。