数组是我们最常见的一种数据格式,通常用于列表的展示。在JS全局作用域上Array内置了很多帮我们处理数组列表的方法,在实战中用的好的话不仅能帮助我们更好的处理数据,提升代码的可观性;代码性能。
下面我们来看看Array内置方法的用法以及具体实战例子吧。
原数组会被改变的方法
1、push
在数组末尾追加一项,并返回原数组改变之后的长度。
arduino
const arr = [1, 2, 3]
const length = arr.push(5)
console.log(arr) // 输出 [1, 2, 3, 4]
console.log(length) // 输出数组追加后的长度 4
应用场景就不需要多说了,基本都是用于数组上的追加一项,例如配置列表上增加一项配置,这时候就需要push往上加一个空的配置对象。需要一提的是对于大量数据的操作,使用 push 方法可能会导致性能问题,因为每次调用 push 方法都会改变数组的长度并重新分配内存。这时候就建议使用扩展运算符,它可以避免这种情况,因为它不会改变原数组的长度。
2、pop
删除并返回数组的最后一个元素。
arduino
const arr = [1, 2, 3]
const last = arr.pop()
console.log(arr) // 输出[1, 2]
console.log(last) // 输出3
删除并返回最后一个元素,这是pop()
最直接的用途。如果你想从数组中删除并返回最后一个元素,你可以使用pop()
方法。例如,你可能正在处理一个用户提交的表单,其中包含多个错误,你想要把最后一个错误信息存储在一个数组中,然后一次性显示出来。
3、shift
删除并返回数组的第一个元素。
arduino
const arr = [1, 2, 3]
const first = arr.shift()
console.log(arr) // 输出[2, 3]
console.log(last) // 输出 1
删除并返回第一个元素,这是shift()
最直接的用途。如果你想从数组中删除并返回第一个元素,你可以使用shift()
方法。例如,浏览器的最大请求数为6,当我们做文件切片上传的时候是需要做请求栈去统一管理请求,先进的就利用shift
先出并执行请求。
4、unshift
向数组的开头添加一个或多个元素,并返回新的长度。
arduino
const arr = [1, 2, 3]
const length = arr.unshift(0)
console.log(arr)
console.log(length)
在数组的开头插入数据,这是unshift
最常用的方法。例如我们需求是希望新增的配置列表永远是排在第一项,这时我们就可以用unshift
去管理我们的数据列表。
5、splice
通过删除或替换现有元素或者添加新元素来修改数组,然后返回被修改的元素,该方法接受三个参数:开始位置
、要删除的元素数量
和要添加的新元素
。
- 开始位置:从哪个位置开始修改数组。
- 要删除的元素数量:从开始位置开始,要删除多少个元素。
- 要添加的新元素:从开始位置开始,要添加多少个新元素。
scss
const arr = [1, 2, 3, 4, 5]
arr.splice(2, 1) // 从索引2开始,删除1个元素
console.log(arr) // 输出 [1, 2, 4, 5]
const arr1 = [1, 2, 3, 4, 5]
arr1.splice(2, 0, 'a', 'b') // 从索引2开始,不删除元素,添加'a'和'b'
console.log(arr1) // 输出 [1, 2, 'a', 'b', 3, 4, 5]
const arr2 = [1, 2, 3, 4, 5]
arr2.splice(2, 2) // 从索引2开始,删除2个元素
console.log(arr2) // 输出 [1, 2,5]
const arr3 = [1, 2, 3, 4, 5]
arr3.splice(2, 1, 5) // 替换索引为2的值
console.log(arr3) // 输出 [ 1, 2, 5, 4, 5 ]
这方法在现实业务上用的还是比较多的,它可以删除配置项的指定元素,也可以插入指定位置的元素,还可以替换数组中任意索引对应的值。例如需要对一个配置列表进行增删改的话,splice
一个方法就可以搞定,只需要控制它自身参数。其他也有不少场景是需要用到它的,得根据自己的需求去处理数据。
6、reverse
它的作用是反转数组中元素的顺序。
scss
const arr = [1, 2, 3, 4, 5]
arr.reverse()
console.log(arr); // 输出: [5, 4, 3, 2, 1]
在某些情况下,你可能需要根据特定条件动态调整数组的顺序。例如,你可能有一个表示时间顺序的数组,并且需要将其反转以表示逆时间顺序。
7、sort
此方法对数组的元素进行排序,并返回数组。默认排序顺序是根据字符串Unicode码点。此方法会改变原数组。
注:b - a指的是降序,前一项减去后一项如果是负数的话就往后诺,反之为升序。
javascript
const arr = [1, 2, 3, 4, 5]
const arr1 = arr.sort((a, b) => b - a)
console.log(arr) // 输出: [5, 4, 3, 2, 1]
console.log(arr1) // 输出: [5, 4, 3, 2, 1]
这方法用的最多的就是排序,对一个表格进行升序降序排序,前端排序可以减少请求节省资源,所以这个还是比较常用的。大部分流行的组件库的表单排序也是用了它。
原数组不会被改变
1、slice
返回包含从 start
到 end
(不包括 end
)新的数组对象,这个对象是一个由原数组的一部分浅拷贝而来。
start
(可选):提取起始索引。如果为负数,表示从数组末尾开始计数的索引。默认值为0。end
(可选):提取结束索引(不包括该索引位置的元素)。如果省略该参数或为负数,则提取到数组末尾。默认值为数组长度。
ini
const arr = [0, 1, 2, 3, 4, 5];
const slicedArr = arr.slice(2); // 从索引2开始,提取到数组末尾
console.log(slicedArr); // 输出 [2, 3, 4, 5]
const slicedArr2 = arr.slice(2, 4); // 从索引2开始,提取到索引4(不包括)
console.log(slicedArr2); // 输出 [2, 3]
const slicedArr3 = arr.slice(-2); // 从数组末尾开始,提取最后两个元素
console.log(slicedArr3); // 输出 [4, 5]
它的用法也很多,例如,你可以从一个数组中提取出一部分元素,创建一个新的数组。这在处理大型数据集时非常有用,因为你可以在不改变原始数据的情况下,对数据进行切片、切块或进行其他操作。
2、concat
连接两个或多个数组。在连接两个或多个数组时,不会改变现有的数组,而是返回被连接数组的一个副本。
ini
const arr = [1, 2, 3]
const arr1 = [4, 5, 6]
const arr3 = [7, 8, 9]
const arr4 = arr1.concat(arr, arr3) // [ 4, 5, 6, 1, 2, 3, 7, 8, 9]
console.log(arr4)
concat本身可以合无限个数组
其主要作用是用作数组的合并,原则上ES6的数组扩展运算符(...)
也可以用于合并数组,且用的较为多,都是对目标数组进行拷贝,并返回,通常被用作下拉加载的数据追加。
3、includes
检查数组是否包含一个指定的值,如果包含则返回true,否则返回false。
arduino
const arr = [1, 2, 3, 4]
console.log(arr.includes(1)) // true
console.log(arr.inclueds(0)) // false
这个方法在判断元素是否存在数组中是比较常用的一种方法,例如,一个列表中需要展现某种选择的字段Key,那么就可以用返回的key和key集合进行includes
,true
则展示,false
则隐藏。
4、forEach
对数组的每个元素执行一次给定的函数,它本身接受两个参数,一个是执行函数,另外一个就是函数作用域里this的绑定对象。
value
: 数组Item本身。index
: 索引,值类型是Number。array
:数组本身。第二个参数thisArg
:绑定函数作用域里的this。
javascript
const obj = {
addItem(item1, item2) {
console.log(item1 + item2)
}
}
const arr = [1, 2, 3]
arr.forEach(function(item, index, array) {
console.log(item, index)
this.addItem(item, index) // 输出调用者的值之和
console.log(array)
}, obj)
注意:绑定forEach里面的this指向不能用箭头函数,因为箭头函数不会创建自己的this
上下文,而是继承自其包含它的函数的this
上下文。因此,箭头函数中的this
指向其包含它的函数中的this
。
forEach在业务中也是用的非常的多,基本循环处理数据列表的时候都会用上它,但是第二个参数估计很多小伙伴都没用过吧。一般调用一些方法集的时候会改变内部this的指向,从而获得某个作用域里的依赖,还是很实用的。
5、map
创建一个新数组,其结果是该数组中的每个元素都调用一个提供的函数后返回的结果。
参数跟forEach一致,这里不多做解释
javascript
const arr = [1, 2, 3]
const arr2 = arr
.map((item, index) => ({ [`${index}`]: item }))
console.log(arr2) // [ { '0': 1 }, { '1': 2 }, { '2': 3 } ]
map在处理数组列表时也是非常的常用,主要用处是改变arr
的内部item
结构,并返回一个新数组。
6、filter
创建一个新数组, 其包含通过所提供函数条件返回为真的所有元素。
参数跟forEach一致,这里不多做解释
ini
const arr = [1, 2, 3]
const arr1 = arr
.filter(item => item === 1)
console.log(arr1) // [ 1 ]
其主要用于对列表的进行过滤,一般用于对不符合条件的数据进行过滤,比如批量删除,则可以用它进行对列表的筛选。
7、some
检测数组中是否有元素通过测试函数。如果有元素通过测试函数,则返回true
;否则,返回false
。
参数跟forEach一致,这里不多做解释
ini
const arr = [1, 2, 3, 4, 5];
const item = arr
.some((c, z, y) => c % 2 === 0);
console.log(item); // true
此方法可以用于检查数组中是否存在至少一个满足指定条件的元素。这对于需要确认数组中是否存在符合特定条件的元素的情况非常有用。它会在找到第一个满足条件的元素时立即返回true
,并终止循环。这可以提高性能,特别是在处理大型数组时。
8、every
检测数组元素是否全部符合指定条件,如果数组中的所有元素都通过测试函数,则返回true
;否则,返回false
。
参数跟forEach一致,这里不多做解释
ini
const arr = [1, 2, 3, 4, 5]
const isNumber = arr
.every(el => (typeof el === 'number'))
console.log(isNumber) // true
此方法通常用于需要对数组中的每个元素进行某种条件判断的场景。具体来说,当你想确认数组中的所有元素是否都满足某个条件时,可以使用它。例如,假设你有一个包含多个数字的数组,并且你想确认数组中的所有数字是否都大于10。你可以使用它来实现这个目标。如果数组中的所有元素都大于10,它将返回true
;否则,返回false
。
需要注意的是some
是有且只有一个符合条件就返回true,every
是所有都通过条件认证之后才会返回true。
9、find
返回数组中满足提供的测试函数的第一个元素的值。否则返回 undefined。
参数跟forEach一致,这里不多做解释
ini
const arr = [1, 2, 3, 4, 5]
const item = arr
.find(c => (c % 2 === 0))
console.log(item) // 2
一般用于根据ID查找目标元素,需要注意的是它找到之后就会终止,不会再往下执行了,所以需要精准条件查询。例如,列表中根据某个ID查看当前列表项的其他数据。
10、findIndex
返回数组中满足提供的测试函数的第一个元素的索引值。否则返回 -1。
参数跟forEach一致,这里不多做解释
ini
const arr = [1, 2, 3, 4, 5]
const index = arr
.findIndex(item => item > 3)
console.log(index) // 输出: 3
一般用于查找复杂数据类型,如获取数组里对象的下标。例如查找当前选中id的索引,需要注意的是,此方法对于空数组不会执行回调函数,直接返回 -1
11、indexOf
查找数组中是否存在某个特定的元素,并返回该元素的第一个索引。如果未找到该元素,则返回-1。
- searchElement: 查找的Value。
- fromIndex[可选] : 查找的起始位置。
注意:主要用于查找基本数据类型,复杂类型请移步findIndex
arduino
const arr = [1, 2, 3, 4, 5]
const index = arr
.indexOf(3, 2)
console.log(index) // 输出: 2
该方法用法非常的广,都是用来判断元素是否存在,并返回存在的索引,例如判断数组中是否存在我们的条件元素,就可以用 !== -1 去判断,但有点需要注意的是他跟String.prototype.indexOf有稍稍不同:
- 对NaN的处理 :在数组中,
indexOf
可以正确地识别出 NaN。但在字符串中,indexOf
不能正确识别出 NaN。例如,"test".indexOf(NaN)
会返回 -1,而[NaN].indexOf(NaN)
会返回 0。 - 对undefined和null的处理 :当目标值是 undefined 或 null 时,它们在数组中会被识别出来,但在字符串中则不会被识别。例如,
"test".indexOf(null)
会返回 -1,而[null].indexOf(null)
会返回 0。
12、reduce
用于将数组中的元素通过指定的函数进行累积,最终返回一个单一的输出值。它可以用来将一个数组简化为一个简单的数据结构,如数字、字符串或对象。
- callbackfn :执行函数(
previousValue前一项
,currentValue当前循环项
,currentIndex当前索引
,array数组本身
) - initialValue:初始默认值
c
const array = [1, 2, 3, 4]
const sum = array
.reduce((accumulator, currentValue) => accumulator + currentValue, 0)
console.log(sum) // 输出: 10
它本身更多的作用是用做累加器,合理的使用它可以代替filter或者map,可以减少循环次数。
13、flat
用于将多维数组展平为一维数组。它通过递归方式处理嵌套数组,并将所有元素收集到一个新数组中。
depth
:可选 。提取嵌套数组的结构深度,默认值为1
。
ini
const arr = [1, [2, [3, [4]], 5], [6, [7, 8]]]
const arr1 = arr
.flat(2)
console.log(arr1) // 输出: [1, 2, 3, [4], 5, 6, [7, 8]]
这个方法可以帮我们递归的去扁平化数组,当处理树形数据的时候可以利用它进行扁平化从而让我们更方便的去拿到列表中的某一项。如果不知道层级,可以传入无限大的层级参数,例如:flat(10000...)。
总结
我们在处理数据的时候难免会跟Array接触,因此合理的利用它本身内置的方法将会大大的提高我们的代码效率和心智负担,甚至提升我们项目的性能。
好了比较常用的方法就介绍到这里啦,应用场景方面的如果有巨佬有更经典的案例请麻烦在评论区留下你们的案例吧,感谢阅读到这里的你!