前言
在开发中,数组的使用场景非常多,现在对其进行归纳总结。
参考:Array - JavaScript | MDN (mozilla.org)
常用的数组方法
| 方法 | 说明 | 参数 | 返回值 | 原数组是否改变 |
|---|---|---|---|---|
| push | 添加一个或多个元素到数组的末尾 | (需要插入的元素) | 操作后的数组长度 | 是 |
| pop | 删除一个数组中的最后一个元素 | 无 | 被删除的元素 | 是 |
| shift | 删除数组的第一个元素,并返回这个元素 | 无 | 被删除的元素 | 是 |
| unshift | 在数组的开头插入一个或多个元素 | (需要插入的元素) | 数组长度 | 是 |
| reverse | 颠倒数组中元素的顺序 | 无 | 操作后数组 | 是 |
| sort | 颠倒数组中元素的顺序 | (无/比较函数) | 操作后数组 | 是 |
| splice | 添加或删除数组中的元素 | (开始索引,要删除数量,要插入值) | 被删除的值(数组形式) | 是 |
| slice | 方法可从已有的数组中返回选定的元素 | (开始索引,结束索引),均可选,可为负数 | 一个含有被提取元素的新数组 | 否 |
| concat | 用于合并两个或多个数组 | (需要拼接的数组) | 操作后的数组 | 否 |
| includes | 数组是否包含给定的值 | (值,索引) 索引可选,默认0,负数表示倒数 | 布尔值 | 否 |
| indexOf | 返回在数组中可以找到一个给定元素的第一个索引 | (值,索引) 索引可选,默认0,负数表示倒数 | 索引 | 否 |
| lastIndexOf | 返回在数组中可以找到一个给定元素的第一个索引 | (值,索引) 索引可选,默认0,负数表示倒数 | 索引 | 否 |
| join | 将数组转为字符串 | (连接符) | 字符串 | 否 |
| forEach | 数组的每个元素执行一次给定的函数 | (cb(index,element, array), thisArg) | undefined | 否 |
| map | 创建一个新数组,这个新数组由原数组中的每个元素都调用一次提供的函数后的返回值组成 | (cb(index,element, array), thisArg) | 一个新数组,每个元素都是回调函数的返回值 | 否 |
| filter | 创建一个原数组的一份浅拷贝,其包含通过所提供函数实现的测试的所有元素 | (cb(index,element, array), thisArg) | 一个通过测试的元素组成的数组,否则为空数组 | 否 |
| find | 返回满足提供的测试函数的第一个元素的值 | (cb(index,element, array), ?thisArg) | 数组中第一个满足所提供测试函数的元素的值,否则为undefined | 否 |
| findIndex | 返回满足提供的测试函数的第一个元素的值的索引 | (cb(index,element, array), ?thisArg) | 数组中第一个满足所提供测试函数的元素的值,否则为-1 | 否 |
| findLast | 返回满足提供的测试函数的最后一个元素的值 | (cb(index,element, array), ?thisArg) | 数组中第一个满足所提供测试函数的元素的值,否则为undefined | 否 |
| findLastIndex | 返回满足提供的测试函数的最后一个元素的值的索引 | (cb(index,element, array), ?thisArg) | 数组中第一个满足所提供测试函数的元素的值,否则为-1 | 否 |
| reduce | 该方法接收一个函数作为累加器(accumulator),数组中的每个值(从左到右)开始合并,最终为一个值 | (cb(preVal,curVal,curIndex, array), initialVal) | 使用回调函数遍历整个数组后的结果。数组为空且初始值 initialVal 未提供,引发TypeError异常 | 否 |
| reduceRight | 该方法接收一个函数作为累加器(accumulator),数组中的每个值(从右到左)开始合并,最终为一个值 | (cb(preVal,curVal,curIndex, array), initialVal) | 使用回调函数遍历整个数组后的结果。数组为空且初始值 initialVal 未提供,引发TypeError异常 | 否 |
| every | 测试一个数组内的所有元素是否都能通过某个指定函数的测试 | (cb(index,element, array), ?thisArg) | 布尔值。空数组:一律返回true | 否 |
| some | 测试一个数组内的至少一个元素能通过某个指定函数的测试 | (cb(index,element, array), ?thisArg) | 布尔值。空数组:一律返回false | 否 |
| keys | 返回一个包含数组中每个索引键的数组迭代器。 | 空 | 一个新的数组迭代器对象 | 否 |
| values | 返回一个包含数组中每个键值对[index,value]数组迭代器。 | 空 | 一个新的数组迭代器对象 | 否 |
| copyWith | 浅复制数组的一部分到同一数组中的另一个位置,并返回它,不会改变原数组的长度。 | (target,start, ?end) | 改变后的数组。 | 是 |
| fill | 方法用一个固定值填充一个数组中从起始索引到终止索引内的全部元素。不包括终止索引。 | (value, ?start, ?end) | 改变后的数组 | 是 |
| flat | 按照一个可指定的深度递归遍历数组,并将所有元素与遍历到的子数组中的元素合并为一个新数组返回。 | (?depth) ,默认值1 | 一个包含将数组与子数组中所有元素的新数组。 | 否 |
| flatMap | 使用映射函数映射每个元素,然后将结果压缩成一个新数组 | (cb(curVal,index, array), | ?thisArg) | 否 |
| at | 返回该索引对应的元素 | (index) | 返回该索引对应的元素,否则为undefined | 否 |
| Array.of | 通过可变数量的参数创建一个新的 Array 实例,而不考虑参数的数量或类型 | 用于创建数组的元素 | 一个新的数组实例 | |
| Array.form | 对一个类似数组或可迭代对象创建一个新的,浅拷贝的数组实例 | (arrayLike,mapFn,?thisArg) | 一个新的数组实例 | |
| Array.isArray | 用于确定传递的值是否是一个 Array | (value) | 布尔值 |
- splice
const arr = [1, 2, 3, 4, 5]
arr.splice(2, 2) // 从下标为2的地方开始删除,删除两个(3,4)
console.log(arr) // [ 1, 2, 5 ]
const arr = [1, 2, 3, 4, 5]
arr.splice(2, 2, 30, 40, 50) // 从下标为2的地方开始删除,删除两个(3,4),然后替换为30, 40, 50
console.log(arr) // [ 1, 2, 30, 40, 50, 5 ]
- reduce
const arr = [1, 2, 4, 8, 16]
const sum = arr.reduce((pre, cur, curIndex) => {
return pre + cur
}, 0)
console.log(sum) // 31
- copyWith
const arr = [1, 2, 4, 8, 16]
const res = arr.copyWithin(2, 1)
console.log(res) // [ 1, 2, 2, 4, 8 ]
常见问题
去重
const arr = [1, 1, 2, 2, 3, 3, 4, 4, 5, 5]
const res = Array.from(new Set(arr))
const res1 = [...new Set(arr)]
console.log(res)
console.log(res1)
排序问题
- 常见问题
- sort方法为无函数时:
const arr = [10, 2, 8, 6, 7]
arr.sort() // [ 10, 2, 6, 7, 8 ]
注意到10在2前面,why?
如果没有指明 compareFn ,那么元素会按照转换为的字符串的诸个字符的 Unicode 位点进行排,所以此时10在2前面,如果指明了compareFn(a, b):
| 返回值 | 排序顺序 |
|---|---|
| > 0 | a在b后 |
| < 0 | a在b前 |
| === 0 | 保持a和b的顺序 |
正确的用法如下:
const arr = [10, 2, 8, 6, 7]
arr.sort((a, b) => {
return a - b
})
console.log(arr) // [ 2, 6, 7, 8, 10 ]
- 自定义排序
const arr = [
{
name: '丙'
},
{
name: '丁'
},
{
name: '甲'
},
{
name: '乙'
}
]
const orders = ['甲', '乙', '丙', '丁']
arr.sort((a, b) => {
return orders.indexOf(a.name) - orders.indexOf(b.name)
})
console.log(arr) // [ { name: '甲' }, { name: '乙' }, { name: '丙' }, { name: '丁' } ]
如何监听数组的变化
- vue2的实现
// 继承Array原来的所有属性和方法
const arrayExt = Object.create(Array.prototype)
const methods = ['push', 'pop', 'shift', 'unshift', 'splice', 'sort', 'reverse']
methods.forEach(method => {
const oldMethod = Array.prototype[method]
const newMethod = function (...args) {
oldMethod.apply(this, args)
console.log(`${method}方法被执行了`)
}
arrayExt[method] = newMethod
})
// 用法
const arr = [1]
arr.__proto__ = arrayExt
arr.push(2)
console.log(arr)
其他问题
-
[, , ,].length等于多少,答案3