JS判断元素是否存在数组中的5种方式总结

 更新时间:2023年03月01日 11:12:51   作者:程序员零壹  
数组是我们编程中经常使用的的数据结构之一,在处理数组时我们经常需要在数组中查找特定的值,下面这篇文章主要给大家总结介绍了关于JS判断元素是否存在数组中的5种方式,需要的朋友可以参考下

前言

在前端开发中, 经常会遇到需要判断某个元素是否存在于数组中的场景。其实判断方法有很多种,今天就跟大家来一起一个一个的了解下。

先来定义一个数组:

const arr = [
13,
false,
'abcd',
undefined,
13,
null,
NaN,
 [1, 2],
 { a: 123 },
() => Date.now(),
new Date('2021/03/04'),
new RegExp('abc', 'ig'),
 Symbol('sym'),
];

在这个数组中,我们包含了好几种类型:number, boolean, string, undefined, null, array, object, Date, Symbol 等。其中数字 13 出现了 2 次。

接下来我们来看下具体实现的方法。

1. indexOf

我们最熟悉的就是indexOf()了,毕竟他出现的早,兼容性也好,使用起来也很方便。

1.1,indexOf

语法:

array.indexOf(item,start)

参数说明:

  • item:必需。要查找的元素。
  • start:可选的整数参数。规定在数组中开始检索的位置。它的合法取值是 0 到 stringObject.length - 1。如省略该参数,则将从字符串的首字符开始检索。

使用方式:

只要判断返回的数据是不是-1,就能知道数组中是否包含该元素。

arr.indexOf(13) >= 0; // true, indexOf返回0
arr.indexOf(false) >= 0; // true, indexOf返回1
arr.indexOf(undefined) >= 0; // true, indexOf返回3
arr.indexOf(2) >= 0; // false, indexOf返回-1

1.2,lastIndexOf

语法:

array.lastIndexOf(item,start)

参数说明:

  • item:必需。要查找的元素。
  • start:可选的整数参数。规定在数组中开始检索的位置。它的合法取值是 0 到 stringObject.length - 1。如省略该参数,则将从字符串的首字符开始检索。

使用方式同indexOf。

1.3,第2个可选参数

indexOf 和 lastIndexOf 还有第 2 个可选参数 start,用来表示从哪个索引开始进行搜索。

在 indexOf 中,若 start超过数组的长度,则直接返回-1,若为负数,则从最后往前数几个索引(arr.length-Math.abs(start)),然后开始往后搜索。

在 lastIndexOf 中,若 start达到或超过数组的长度,则搜索整个数组;若为负数,则从最后往前数几个索引(arr.length-Math.abs(start)),然后开始往前搜索,若负数的绝对值超过了数组的长度,则直接返回-1。

arr.indexOf(13, 2); // 4, 从索引值2开始往后查找,首先找到的13的索引值为4
arr.indexOf(13, -10); // 4, 从索引值1(11-10)开始往后检索
arr.lastIndexOf(13, 2); // 0, 从索引值2往前开始搜索
arr.lastIndexOf(13, -2); // 4, 从索引值9(11-2)开始往前搜索

2. includes

includes() 方法用来判断一个数组是否包含一个指定的值,如果是返回 true,否则false。

语法:

array.includes(searchElement, fromIndex)

参数说明:

  • searchElement:必须。需要查找的元素值。
  • fromIndex:可选。从该索引处开始查找 searchElement。如果为负值,则按升序从 array.length + fromIndex 的索引开始搜索。默认为 0。

使用方式:

arr.includes(13); // true
arr.includes('abc'); // false
arr.includes(false); // true, 存在false元素

同时,includes() 方法中也存在第 2 个可选参数 fromIndex,fromIndex 的用法与 indexOf() 中的一样。若 fromIndex 超过数组的长度,则直接返回-1,若为负数,则从最后往前数几个索引(arr.length-Math.abs(fromIndex)),然后开始往后搜索。

arr.includes(13, 1); // true, 从索引值1开始往后检索,可检索到
arr.includes(13, 5); // false, 从索引值5开始往后检索,没检索到
arr.includes(13, -8); // false, 从最后元素往前数8个索引,没检索到
arr.includes(13, -9); // true, 从最后元素往前数9个索引,可检索到

到目前为止,后面的几种类型,例如 Array, Object, Date 和 Symbol,我们都没判断呢。我们现在来判断下后面的几个元素:

// 使用indexOf判断
arr.indexOf(NaN); // -1
arr.indexOf([1, 2]); // -1
arr.indexOf({ a: 123 }); // -1
arr.indexOf(() => Date.now()); // -1
arr.indexOf(new Date('2021/03/04')); // -1
arr.indexOf(new RegExp('abc', 'ig')); // -1
arr.indexOf(Symbol('sym')); // -1
​
// 使用includes判断
arr.includes(NaN); // false
arr.includes([1, 2]); // false
arr.includes({ a: 123 }); // false
arr.includes(() => Date.now()); // false
arr.includes(new Date('2021/03/04')); // false
arr.includes(new RegExp('abc', 'ig')); // false
arr.includes(Symbol('sym')); // false

结局很惨,这几种元素在数组中都没有检索到。可是实际上在数组中都是真实存在的。

这是因为 indexOf 和 includes 都是采用严格相等的方式(===)来判定的。

NaN === NaN; // false, 两个NaN永远也不会相等
[1, 2] === [1, 2]; // false, 每个声明出来的数组都有单独的存储地址
{a: 123} === {a: 123}; // false, 同数组
new Date('2021/03/04')===new Date('2021/03/04'); // false, 看着日期是相同的,但是用new出来的对象进行比较的,肯定是不相等的
Symbol('sym')===Symbol('sym'); // Symbol类型的出现就是为了避免冲突创造出来的类型,括号里的属性仅是为了方便描述而已

针对这些无法被检索的类型,我们就需要自己写函数来判断特殊的类型了。

3. some

some() 方法用于检测数组中的元素是否满足指定条件(函数提供)。some() 方法会依次执行数组的每个元素:如果有一个元素满足条件,则表达式返回true , 剩余的元素不会再执行检测;如果没有满足条件的元素,则返回false。注意:some() 不会对空数组进行检测,也不会改变原来数组。

语法:

array.some(function(currentValue,index,arr),thisValue)

参数说明:

  • function(currentValue, index,arr):必须。函数,数组中的每个元素都会执行这个函数。

函数参数:

  • currentValue:必须。当前元素的值。
  • index:可选。当前元素的索引值。
  • arr:可选。当前元素属于的数组对象。
  • thisValue:可选。对象作为该执行回调时使用,传递给函数,用作 "this" 的值。如果省略了 thisValue ,"this" 的值为 "undefined"。

使用方式:

arr.some((item) => item === false); // true
arr.some((item) => item === undefined); // true
arr.some((item) => typeof item === 'number' && isNaN(item)); // true
arr.some((item) => item === 3); // false, 不存在数字3
arr.some((item) => {
 if (item instanceof Date) {
  return item.toString() === new Date('2021/03/04').toString();
 }
 return false;
}); // true

4. filter

filter() 方法创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素。filter() 不会对空数组进行检测,也不会改变原有数组。

语法:

array.filter(function(currentValue,index,arr),thisValue)

​参数说明:

  • function(currentValue, index,arr):必须。函数,数组中的每个元素都会执行这个函数。

函数参数:

  • currentValue:必须。当前元素的值。
  • index:可选。当前元素的索引值。
  • arr:可选。当前元素属于的数组对象。
  • thisValue:可选。对象作为该执行回调时使用,传递给函数,用作 "this" 的值。如果省略了 thisValue ,"this" 的值为 "undefined"。

使用方式:

arr.filter((item) => item === false); // [false]
arr.filter((item) => item === undefined); // [undefined]
arr.filter((item) => typeof item === 'number' && isNaN(item)); // [NaN]
arr.filter((item) => item === 13); // [13,13]
arr.filter((item) => item === 3); // []
arr.filter((item) => {
 if (item instanceof Date) {
  return item.toString() === new Date('2021/03/04').toString();
 }
 return false;
}); // [Thu Mar 04 2021 00:00:00 GMT+0800 (中国标准时间)]

因此我们可以通过该数组的长度,来判断原数组是否包含我们想要的元素。

5. find

find() 方法返回通过测试(函数内判断)的数组的第一个元素的值。find() 方法为数组中的每个元素都调用一次函数执行:当数组中的元素在测试条件时返回 true 时, find() 返回符合条件的元素,之后的值不会再调用执行函数;如果没有符合条件的元素返回 undefined。find() 对于空数组,函数是不会执行的,也不会改变原有数组。

find()方法无法检测数组中的 undefined 元素。因为不存在和存在 undefined 元素,find()方法都会返回 undefined。这里我们就要考虑其他方式了,稍后再讲。

语法:

array.find(function(currentValue, index, arr),thisValue)

参数说明:

  • function(currentValue, index,arr):必须。函数,数组中的每个元素都会执行这个函数。

函数参数:

  • currentValue:必须。当前元素的值。
  • index:可选。当前元素的索引值。
  • arr:可选。当前元素属于的数组对象。
  • thisValue:可选。对象作为该执行回调时使用,传递给函数,用作 "this" 的值。如果省略了 thisValue ,"this" 的值为 "undefined"。

使用方式:

arr.find((item) => item === 13); // 13, 找到了元素13
arr.find((item) => item === 3); // undefined, 没找到元素3
arr.find((item) => item === undefined); // undefined, 也不知道是找到了还是没找到

对于给定数组的稍微复杂点的数据类型,我们就需要做一些特殊的判断了。

arr.find((item) => typeof item === 'number' && isNaN(item)); // NaN
​
// array和object类型进行比较时,情况很复杂,因为每个元素的类型都无法确定
// 如果确定都是基本类型,如string, number, boolean, undefined, null等,可以将其转为字符串再比较
// 转字符串的方式也很多,如JSON.stringify(arr), arr.toString(), arr.split('|')等
// 复杂点的,只能一项一项比较,或者使用递归
arr.find((item) => item.toString() === [1, 2].toString()); // [1, 2]
arr.find((item) => JSON.stringify(item) === JSON.stringify({ a: 123 })); // {a: 123}
arr.find((item) => {
 if (typeof item === 'function') {
 return item.toString() === (() => Date.now()).toString();
 }
 return false;
}); // () => Date.now()
arr.find((item) => {
 if (item instanceof Date) {
 return item.toString() === new Date('2021/03/04').toString();
 }
 return false;
}); // Thu Mar 04 2021 00:00:00 GMT+0800
arr.find((item) => {
 if (item instanceof RegExp) {
 return item.toString() === new RegExp('abc', 'ig').toString();
 }
 return false;
}); // /abc/gi
​
// Symbol确实没法比较,只能比较描述是否一样
arr.find((item) => {
 if (typeof item === 'symbol') {
 return item.toString() === Symbol('sym').toString();
 }
 return false;
}); // Symbol(sym)

如果还要判断数组中是否存在 undefined,我们可以使用findIndex()方法。findIndex() 方法返回数组中满足提供的测试函数的第一个元素的索引。若没有找到对应元素则返回-1。

arr.findIndex((item) => item === undefined); // 3
arr.findIndex((item) => item === 3); // -1, 没有找到数字3

其他数据格式的判断,与上面的 find()一样。

6. 总结

判断某个元素是否在数组中的方式有很多种,我们可以根据数组中元素的格式,来选择更合适的方式。如果都是一些基本类型,建议优先选择使用includes()方法;如果格式比较复杂的,建议选择使用some()方法。这两个方法都是直接返回 boolean 类型,无需更多的转换即可直接使用方法的结果。

到此这篇关于JS判断元素是否存在数组中的5种方式总结的文章就介绍到这了,更多相关JS判断元素是否存在数组内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 单击浏览器右上角的X关闭窗口弹出提示的小例子

    单击浏览器右上角的X关闭窗口弹出提示的小例子

    单击浏览器右上角的X关闭窗口弹出提示的小例子,需要的朋友可以参考一下
    2013-06-06
  • three.js中文文档学习之通过模块导入

    three.js中文文档学习之通过模块导入

    这篇文章主要给大家介绍了关于three.js中文文档学习之通过模块导入的相关资料,文中通过示例代码介绍的非常详细,对大家学习或使用three.js具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧。
    2017-11-11
  • JS命令模式例子之菜单程序

    JS命令模式例子之菜单程序

    这篇文章主要为大家详细介绍了JS命令模式例子之菜单程序,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-10-10
  • 图片上传插件jquery.uploadify详解

    图片上传插件jquery.uploadify详解

    如果页面没有显示“BROWSE”按钮,则说明你的'uploader' : '<%=basePath%>images/uploadify.swf'配置不对,检查下路径是否正确
    2013-11-11
  • js实现轮播图的完整代码

    js实现轮播图的完整代码

    这篇文章主要为大家详细介绍了js实现轮播图的完整代码,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-08-08
  • 微信小程序调用微信支付接口的实现方法

    微信小程序调用微信支付接口的实现方法

    这篇文章主要介绍了微信小程序调用微信支付接口,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-04-04
  • javascript实现动态时钟的启动和停止

    javascript实现动态时钟的启动和停止

    这篇文章主要为大家详细介绍了javascript实现动态时钟的启动和停止文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-10-10
  • JavaScript惰性求值的一种实现方法示例

    JavaScript惰性求值的一种实现方法示例

    这篇文章主要给大家介绍了关于JavaScript惰性求值的一种实现方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-01-01
  • Javascript实现秒表计时游戏

    Javascript实现秒表计时游戏

    这篇文章主要为大家详细介绍了Javascript实现秒表计时游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-05-05
  • JavaScript递归函数定义与用法实例分析

    JavaScript递归函数定义与用法实例分析

    这篇文章主要介绍了JavaScript递归函数定义与用法,结合实例形式分析了javascript递归的原理、函数定义、使用方法及操作注意事项,需要的朋友可以参考下
    2019-01-01

最新评论