盘点数组Array方法
前言
数组在js中作为一个非常重要的类型之一,在我们对数据处理,存储数据,条件渲染的时候经常会用到,所以随着ES的不断更新,数组的方法也是越来越多,也让我们使用数组对数据操作的时候,越来越简单,但是不经意间,数组的方法已经有42个之多,接下来让我们看看有哪些数组方法从出来就你还没用过的吧!
数组方法
数组方法之多,大致可以分为以改变数组本身的,不改变数组本身的(返回一个新的数组),还有就是其他对数组本身功能性作用的方法
1. ⭐改变原数组(9个)
1.1 unshift & push 塞元素
- unshift:往数组开头塞入元素,可塞入多个
- push:往数组末尾塞入元素,可塞入多个
1 | const arr = [ 1, 2, 3, 4, 5 ] |
1.2 shift & pop 除去元素
- shift:把数组开头的元素去除,并返回这个元素
- pop:把数组末尾的元素去除,并返回这个元素
1 | const arr = [ 6, 1, 2, 3, 4, 5 ] |
1.3 sort 排序
用来排序数组的,并且你也可以自定义排序规则,只需要传入一个函数即可
进行对数组就地排序,不会复制或返回一个新数组,接收可选参数,一个回调函数。
有a,b两个参数:
当返回a<b时返回-1从小到大排序,升序
当返回a>b时返回1从大到小排序,降序
a==b时返回0,保持原来的排序(默认排序是将元素转换为字符串,然后按照它们的 UTF-16 码元值升序排序。)
1 | const arr = ["March", "Jan", "Feb", "Dec", 6, 2, "A", "a"]; |
1.4 reverse 反转
用来反转数组的
1 | const arr = ["March", "Jan", 6, 2, "A", "a"]; |
1.5 splice 截取
通常被用来截取数组,可传入:
第一个为截取的索引位置,number类型,从哪个索引开始截取
第二个截取的个数,number类型,截取几个元素
第三个或更多实在截取位置添加的参数,截取后可塞进新的元素,任何参数
这个方法的返回结果是被截取的部分
1 | const arr = ["March", "Jan", 6, 2, "A", "a"]; |
1.6 fill 填充
用来把数组填满成自己想要的元素
对数组内容进行覆盖填充,有三个参数:
第一个为填充值,
第二个为起始位置(可选),
第三个为结束位置,不包含此索引位置(可选)。
与
copyWithin
比较类似,只不过一个是移动数组内的元素,一个填充数组的内的元素,不会改变数组的长度。并返回这个数组。
1 | const arr1 = ["March", "Jan", 6, 2, "A", "a"]; |
1.7 copyWithinArr 复制替换
有点类似于 splice,不过也有些不同,copyWithinArr 可以把某一个索引的元素去除,并拿数组本身的元素剪切复制进去这个索引的位置
copyWithin
是一种移动数组数据的高性能方法,copyWithin()
方法是通用的。它只期望this
值具有length
属性和整数键属性。虽然字符串也是类似数组的,但这种方法不适用于它们,因为字符串是不可变的。copyWithin不会改变数组的长度,只会修改内容,它接收三个参数:
第一个为复制到的目标位置(索引值),
第二个是复制的起始位置(可选),如果为负数,则相当于从后往前数,
第三个为结束位置,不包含此索引的位置(可选),
结束位置大于起始位置,同为正或同为负,否者方法无效。并返回这个原数组。
起始位置间隔大于1,则是剪切
起始位置间隔等于1,则是复制
1 | //起始位置间隔大于1,则是剪切 |
2. 不变原数组(30个)
2.1 ⭐forEach 循环遍历
通常用来遍历,其实跟 for 的作用差不多,不过 for 支持 await 排队且 for 能终止和跳过某次步骤,forEach 不支持
1 | arr = ['sunshine_lin','sanxin_lin','digger_lin'] |
2.2 ⭐map 处理元素返回新数组
把数组的每一项都通过自定义规则去修改,并返回成一个新的数组
map方法只是单纯的返回一个新数组,可以是处理后的,也可以是原数组,接收一个回调函数,回调函数有三个参数
第一个是当前遍历的元素,
第二个为当前索引,
第三个是数组本身,
需要一个返回值,从map内部处理过后,回调函数的返回值返回一个新数组
1 | const arr = ["March", "Jan", 6, 2, "A", "a"]; |
2.3 ⭐filter 过滤
用来过滤的,接收一个过滤函数,返回 假值 的元素会被过滤掉,返回 真值 的则会被保留
需要一定条件返回对应的数据,接收一个回调函数,有回调函数有三个参数,
第一个是当前遍历的元素,
第二个为当前索引,
第三个是数组本身,
需要一个返回值,filter方法会根据符合这个返回值条件的数据返回一个新数组
1 | const arr = ["March", "Jan", 6, 2, "A", "a"]; |
2.4 ⭐reduce 累积计算
通常会用来:
- 根据数组每一项计算总数
- 根据数组每一项计算出一个Map
reduce
是一个功能非常强大的方法,但平常很少使用,因为他的功能他的方法都可以实现,它也能实现其他的一些方法,有时候合理的使用reduce
会大大减少代码量。接收两个参数:第一个为回调函数,回调函数有四个参数:
- 参数1 为上一次回调函数
return
的结果,首次默认为第二个参数值,如果没有第二个参数值,则默认当前数组下标为0的参数,- 参数2 为当前元素,
- 参数3 为当前索引值,
- 参数4 为数组本身
第二个参数指定一个默认值,可选
1 | //使用reduce实现filter方法 |
2.5 reduceRight 累积计算
作用跟 reduce 一模一样,只不过 reduceRight 是从后往前去遍历
这个是
reduce
的右边开始一种写法,运算时会从右向左执行,参数与使用方法和reduce
一致。适用于当你想对一个数组进行反转加过滤等操作的时候,这个方法就完全突出了他的便携
1 | const arr = ["March", "Jan", 6, 2, "A", "a"]; |
2.6 ⭐slice 截取
用来截取数组的,第一个参数是起始索引,第二个参数是终止索引,但是不会截取终止索引的元素
可以对一个数组进行浅拷贝,接收两个参数:
第一个为截取的初始位置,
第二个为终止位置(不包括此索引值),
如果只填一个参数则从当前索引值截取到最后一位
1 | const arr = ["March", "Jan", 6, 2, "A", "a"]; |
2.7 ⭐every 所有必须真
传入一个计算函数,需要所有元素的计算结果都返回 真值,最终方法才会返回 true,只要有一个 假值,那么最终会返回 false
every
用于所有元素是否都能通过测试,返回一个布尔值,只有当所有元素都通过了测试,才会返回true
,接收一个回调函数,回调函数有三个形参:
第一个为当前元素,
第二个为当前索引,
第三个为数组本身,
另外,当数组为空的时候使用every,条件不论是怎么样的,都会返回true(这种情况属于无条件正确,因为空集的所有元素都符合给定的条件。)
1 | const arr = ["March", "Jan", 6, 2, "A", "a"]; |
2.8 ⭐some 至少一个真
传入一个计算函数,至少要有一个元素的计算结果返回 真值,最终方法才会返回 true,如果所有都返回 假值,那么最终会返回 false
some用于数组中参数其中一个或多个通过了测试,返回一个布尔值,如果有一个或以上通过测试就返回true,一个都没通过返回false,
接收一个回调函数,有三个形参:
第一个为当前元素,
第二个为当前索引,
第三个为数组本身,
另外,当数组为空时使用some,不论判断条件如何,都会返回false,并且他不会改变数组
1 | const arr = ["March", "Jan", 6, 2, "A", "a"]; |
2.9 ⭐concat 拼接
用来拼接两个数组,并返回拼接后的数组
需要两个或以上的数组合并的时候就可以使用
concat
快速合并,当然在ES6之后大多都使用扩展运算符进行数组合并了,此方法接收一个或以上得任意类型参数
1 | const arr1 = ["March", "Jan"]; |
2.10⭐ join 拼接分隔符转字符串
用的频率很高的一个方法,传入一个分隔符,把数组转成一个字符串
join用于将数组转换成字符串的方法,接收一个参数(可以为任意类型,但引用类型则会默认转换成[object Object]等),为数组元素转换成字符串的间隔符,不传参数默认以 ‘,’号隔开
1 | const arr = ["March", "Jan", 6, 2, "A", "a"]; |
2.11 ⭐flat 扁平
用来把数组扁平化,传入一个数字,可以控制需要扁平多少层,如果传入 Infinity ,则会完全扁平化
通常在扁平化数组的时候都要使用递归函数,flat方法避免了页面中写递归函数造成大量的代码冗余,flat本身也是使用递归方法来达到数组扁平化的,接收一个number类型的参数,参数是几就可以扁平几层,在不确定有几维数组的情况下,参数为Infinity(无限大),可以扁平任意层次的数组
1 | arr=[['sunshine_lin',['三心小子',['三心弟']]],'sanxin_lin','digger._Lin'] |
2.12 flatMap 扁平
也是做扁平化的,传入一个函数,函数返回的结果如果是一个数组,最终计算出来的的最终结果中,这个数组会被拍平,这个方法应该很少人用
flatMap与map相似,都是接收一个回调函数,进行处理后返回一个数组,但有一处差别就是flatMap可以对数组进行一层扁平化(仅数组)
1 | const arr1 = ["March", "Jan", 6, 2, "A", "a"]; |
2.13 ⭐indexOf & lastIndexOf 查找索引
传入一个数组元素,能查出这个元素在数组中的第一个索引,如果查不到则返回 -1
注意:这两个方法查不了 NaN 的索引
indexOf:从前往后查
写法和includes类似,有两个参数第一个是要找的值,第二个为开始索引,indexOf会在查找到第一个符合条件的参数跳出循环并返回索引,没找到则返回-1
lastIndexOf:从后往前查
与indexOf一致,只不过是返回最后的索引位置,也可以理解为他是从数组的右边开始往左找元素,并返回第一个找到的元素的索引,没找到则返回-1
1 | //indexOf |
2.14 ⭐includes 包含
传入一个数组元素,查出这个元素是否存在这个数组中,返回一个布尔值
注意:includes 可以查出数组是否包含 NaN
在数组中查抄某一个值,返回一个布尔值,有两个参数:
第一个你要查找的值,
第二个从哪个索引位置开始找
1 | const arr = ["March", "Jan", 6, 2, "A", "a"]; |
2.15 ⭐find & findLast 寻找元素
传入一个计算函数,根据这个计算函数的返回结果,查出数组中第一个计算返回真值的元素
find:从前往后查
find
查找符合条件的的一个元素并返回那个元素本身,没有则返回undefined
接收一个回调函数,回调函数有三个形参:
- 第一个当前元素,
- 第二个当前索引,
- 第三个数组本身
findLast:从后往前查
此方法兼容性不好,暂时不推荐使用,node版本需要18.0.0以上 与
find
使用方法一致,findLast
从右向左查找符合条件的的一个元素,并返回那个元素,没有则返回undefined
1 | //find:从前往后查 |
2.16 findIndex & findLastIndex 寻找索引
传入一个计算函数,根据这个计算函数的返回结果,查出数组中第一个计算返回真值的元素的索引
findIndex:从前往后查
与
find
使用方法一致,findIndex
查找符合条件的的一个元素并返回那个元素的索引值,没有则返回-1接收一个回调函数,回调函数有三个形参:
- 第一个当前元素,
- 第二个当前索引,
- 第三个数组本身
findLastIndex:从后往前查
此方法兼容性不好,暂时不推荐使用,node版本需要18.0.0以上 与
findLast
使用方法一致,findLastIndex
从右向左查找符合条件的的一个元素,并返回那个元素的索引值,没有则返回-1
1 | //findIndex:从前往后查 |
2.17 at 寻找元素
传入一个索引值,查出此索引值所对应的元素,传入负数的话,相当于 arr.length + index
此方法兼容性一般,暂时不推荐使用,node版本需要16.6.0以上 at接收一个number的参数,可以为负数,正数时获取到索引为的值,当参数为负数时,从右向左查找对应的值
1 | const arr = ["March", "Jan", 6, 2, "A", "a"]; |
2.18 of 生成数组
你可以理解为他可以用来生成一个数组吧,平时很少用
1 | const newArr = Array.of("March", "Jan", 6, 2, "A", "a"); |
2.19 ⭐toString 转字符串
它等同于 arr.join(‘,’),将数组用逗号分隔,转成一个字符串
toString
是几乎所有数据类型都有的一个方法,就是单纯的转换成字符串,数组中转换成字符串默认以‘,’号隔开,有一个小技巧,如果多维数组的类型都是值类型的,可以使用toString进行扁平化
1 | //简单的数组转字符串 |
2.20 toLocaleString 转字符串
toLocaleString() 方法返回一个字符串,表示数组中的所有元素。每个元素通过调用它们自己的 toLocaleString 方法转换为字符串,并且使用特定于语言环境的字符串(例如逗号“,”)分隔开
此方法用于格式转换,最后返回字符串代表数组中所有的元素,接收两个参数第一个带有 BCP 47 语言标签的字符串,或者此类字符串的数组。对于
locales
参数的一般形式和说明,可以参见Intl
主页面的参数说明。第二个,一个具有配置属性的对象。对于数字,请参见Number.prototype.toLocaleString()
;对于日期,请参见Date.prototype.toLocaleString()
。此方法的使用方法记得东西比较多,详细使用方法可以点击上面的链接查看
1 | const arr = ["¥7", 500, 8123, 12]; |
2.21 ⭐keys 返回索引集合可迭代对象
获取数组的所有索引,并返回成一个可迭代对象
返回一个只包含键的迭代对象,使用方法与entries一致
1 | const arr = ["March", "Jan", 6, 2, "A", "a"]; |
2.22 ⭐values 返回元素集合可迭代对象
获取数组的所有元素,并返回一个可迭代对象
返回一个只包含值得可迭代对象,使用方法与entries一致
1 | const arr = ["March", "Jan", 6, 2, "A", "a"]; |
2.23 ⭐entries 返回键值对集合可迭代对象
获取的数组的所有索引和元素,组成一个一个的键值对数组,并返回一个可迭代对象
返回一个数组迭代器对象,数组迭代器( array[Symbol.iterator]),
如果不太清楚的可以看一下Symbol篇章,或者点击数组迭代器查看
1 | const arr = ["March", "Jan", 6, 2, "A", "a"]; |
2.24 Array 生成数组
1 | console.log(Array(8)) |
2.25 Array.form & 拓展运算符 转化
- Array.from:把一个类数组转成真正的数组
- 拓展运算符:把一个类数组转成真正的数组,也可以用于剩余参数,数组解构
此方法可以将一些可迭代的以及为数组的数据转换成真正的数组,并返回一个那个新数组,比如字符串,dom伪数组等,
接收两个参数:
第一个为要转化的参数,
第二个是一个回调函数(可选)
回调函数有两个参数当前遍历的对象和索引
1 | const newArr = Array.from("March"); |
2.26 Array.formAsync
Array.fromAsync() 静态方法可以由一个异步可迭代对象、可迭代对象或类数组对象创建一个新的、浅拷贝的 Array 实例。
我理解它是 Array.from 的异步版本
Array.fromAsync()
迭代异步可迭代对象的方式与for await...of
很相似。Array.fromAsync()
在行为上与Array.from()
几乎等价
Array.fromAsync()
可以处理异步可迭代对象。Array.fromAsync()
返回一个会兑现为数组实例的Promise
。- 如果使用非异步可迭代对象调用
Array.fromAsync()
,则要添加到数组中的每个元素(无论是否为 Promise)都会先等待其兑现。- 如果提供了
mapFn
,则其输入和输出会在内部等待兑现。
Array.fromAsync()
和Promise.all()
都可以将一个 promise 可迭代对象转换为一个数组的 promise。然而,它们有两个关键区别:
Array.fromAsync()
会依次等待对象中产生的每个值兑现。Promise.all()
会并行等待所有值兑现。Array.fromAsync()
惰性迭代可迭代对象,并且不会获取下一个值,直到当前值被兑现。Promise.all()
预先获取所有值并等待它们全部兑现。
1 | //我也没用过,凑合看吧 手动滑稽(≧∇≦)ノ |
2.27 ⭐Array.isArray 判断类型
用来判断一个数据的类型是否为数组
也可用instanceof,参考检测数组
在类型判断的时候,我们通常使用
typeof
,但是使用typeof
的时候数组判断出来的就是Object
类型,可以说数组是特殊的对象,使用typeof
判断不出数组,就可以使用Array.isArray
方法
1 | (function () { |
3. 兼容性不好的数组方法(4个)
接下来讲一些比较新的方法,它们得要有高版本的浏览器或者nodejs版本才支持,否则不支持
3.1 toReversed 反转
用法和 reverse 大致一样,唯一不同的就是 reverse 会改变原数组,但是 toReversed 是返回一个全新的反转后的数组,
并不会修改原数组
此方法兼容性不好,暂时不推荐使用,node版本需要20.0.0以上,浏览器就不用说了
使用
reverse
可以反转数组,但是会改变原数组,如果不想让原数组改变的并反转数组的话就可以使用它的复制版本toReveresed
1 | const arr1 = ["March", "Jan", 6, 2, "A", "a"]; |
3.2 toSorted 排序
用法和 sort 大致一样,唯一不同的就是 sort 会改变原数组,但是 toSorted 是返回一个全新的排序后的数组,
并不会修改原数组
此方法兼容性不好,暂时不推荐使用,node版本需要20.0.0以上,浏览器就不用说了
使用
sort
可以反转数组,但是会改变原数组,一样的可以使用toSorted
,不会改变原数组,会返回一个排好序的数组,接受的参数和sort
一致,参考sort
1 | const arr1 = ["March", "Jan", 6, 2, "A", "a"]; |
3.3 toSpliced 截取
用法和 splice 大致一样,唯一不同的就是 splice 会改变原数组,但是 toSpliced 并不会修改原数组
此方法兼容性不好,暂时不推荐使用,node版本需要20.0.0以上,浏览器就不用说了
使用
splice
可以对数组进行截取和指定位置新增数据,但是会改变原数组,可以使用toSpliced
,不会改变原数组,会返回一个新的数组,接受的参数使用方法和splice
一致,参考splice
1 | const arr1 = ["March", "Jan", 6, 2, "A", "a"]; |
3.4 with 修改
以前想修改数组的某个元素,需要通过索引去修改,但是这样会修改到原数组,而使用 with 去修改的话,不会影响原数组
此方法兼容性不好,暂时不推荐使用,node版本需要20.0.0以上,浏览器就不用说了
我们都知道,我们再修改数组中得某一个值得时候可以使用
arr[index]=xxx
来进行修改,但是这样是改变了原数组,当我们既想使用索引值来改变某一个值,还不想改变原数组得时候就可以使用with
方法,它接收两个参数:第一个为索引值,
第二个是要修改成为数据
1 | const arr = ["March", "Jan", 6, 2, "A", "a"]; |
4. ⭐巧用数组作判断
项目中的一个小需求点,点击按钮,验证几十个条件框,判断所有条件框是否填写(选择)过数据(至少有一个条件判断为真)再执行对应操作
判断的条件框包含 Radio 单选框,Checkbox 多选框,Input 输入框,InputNumber 计数器, Select 选择器, Switch 开关等
项目使用的 Element 组件库 V2.15.6
4.1 不同条件对应的数据类型以及默认值
- Radio 单选框
string
''
- Checkbox 多选框
array
[]
- Input 输入框
string
''
- InputNumber 计数器
number
0
- Select 选择器
- 单选
string
''
- 多选
array
[]
- 单选
- Switch 开关
boolean
false
4.2 代码实现
思路一
直接用 if
判断开干,然后大概代码如下(变量为模拟变量)
1 | // 多条件判断开始,如下 |
实际项目场景中的变量名因为语义化字符很多, if
判断没写几个就写了很长一串, 然后写了几个就写不动了(感觉在写一坨 shi )
能不能用更优雅的方式实现呢?
思路二
把这些需要判断的变量放到一个数组里,用 map
处理,使用 includes
判断数组中是否包含指定的 Boolean
值
1 | // 多条件判断开始,如下 |
思路三
把这些需要判断的变量放到一个数组里,用 some处理成 Boolean
类型,会自动返回Boolean值
1 | const arr = [ |