JavaScript 数组方法速通**李佳琪** 曾经说过:今天你有没有好好利用 JavaScript 数组的方法?这么
JavaScript数组方法速通
李佳琪 曾经说过:今天你有没有好好利用 JavaScript 数组的方法?这么多年你技术涨没涨?你是不是还不会用 flatMap() 这类新方法来减少filter 链式 map的使用呢?有没有了解过 toSpliced()、toReversed() 和 toSorted() 新数组方法呢?是不是还在使用 arr[arr.length-1] 获取最后的数组元素?... 看看自己进步了没有!”

答:嗨呀我知道了,马上。。。
常用方法(必须掌握)
原数组
const array = [{ id: 1, name: 'tom', age: 14 }, { id: 2, name: 'sam', age: 16 }, { id: 3, name: 'linlin', age: 16 }]
1. filter
const filterArray = array.filter(item => item.age === 16)
-
功能:
filter会遍历数组,并根据条件返回一个新数组,包含所有满足条件的元素。 -
输出:
[{ id: 2, name: 'sam', age: 16 }, { id: 3, name: 'linlin', age: 16 }] -
相似API:
find和some。区别在于:filter返回 所有 满足条件的元素数组。find返回 第一个 满足条件的元素。some只是检查是否 至少有一个 满足条件的元素,返回布尔值。
-
使用场景: 当你需要筛选出一组满足某些条件的元素时,例如查找所有符合某个年龄的人群。
2. map
const mapArray = array.map(item => item.name)
-
功能:
map会遍历数组并根据提供的函数返回每个元素的新值,生成一个新数组。 -
输出:
['tom', 'sam', 'linlin'] -
相似API:
forEach。区别在于:map返回一个新的数组。forEach只用于执行副作用(不返回值),例如打印日志或更新外部变量。
-
使用场景: 当需要提取某些属性或对每个元素进行转换。例如,从对象数组中提取所有
name字段。
3. find、findIndex、findLast、findLastIndex
const findArray = array.find(item => item.age === 16)
const findIndexArray = array.findIndex(item => item.age === 16)
const findLastArray = array.findLast(item => item.age === 16)
const findLastIndexArray = array.findLastIndex(item => item.age === 16)
-
功能:
find返回第一个满足条件的元素。findIndex返回第一个满足条件元素的索引。findLast返回从后向前第一个满足条件的元素。findLastIndex返回从后向前第一个满足条件元素的索引。
-
输出:
findArray:{ id: 2, name: 'sam', age: 16 }findIndexArray:1findLastArray:{ id: 3, name: 'linlin', age: 16 }findLastIndexArray:2
-
相似API:
filter。区别在于:find只返回第一个满足条件的元素。filter返回所有满足条件的元素。
-
使用场景: 当你只关心第一个符合条件的结果或其索引时。例如,查找数组中的第一个特定值或从后向前查找。
4. forEach、for...in、for...of
array.forEach(item => { ... })
for (const key in array) { ... }
for (const value of array) { ... }
-
功能:
forEach遍历数组的每个元素并执行回调函数,不返回值。for...in遍历数组的索引。for...of遍历数组的值。
-
输出: 无返回值,仅执行副作用(例如打印日志)。
-
相似API:
map。区别在于:forEach是副作用函数,不返回值。map返回一个新数组。
-
使用场景: 当你只需要对每个元素进行操作,而不关心返回值时。例如,遍历一个数组并执行一些逻辑,如日志记录或修改外部变量。
5. pop、push、shift、unshift
deepCloneArray.pop()
deepCloneArray.push({ id: 4, name: 'jack', age: 18 })
deepCloneArray.shift()
deepCloneArray.unshift({ id: 5, name: 'jerry', age: 20 })
-
功能:
pop删除数组最后一个元素。push添加元素到数组末尾。shift删除数组的第一个元素。unshift添加元素到数组的开头。
-
输出:
pop: 删除并返回最后一个元素。push: 返回新数组的长度。shift: 删除并返回第一个元素。unshift: 返回新数组的长度。
-
相似API:
splice。区别在于:splice可以从数组的任何位置插入或删除元素。pop和push仅对数组末尾操作,shift和unshift仅对开头操作。
-
使用场景: 常用于堆栈和队列的实现,例如
push和pop实现堆栈,shift和unshift实现队列。
6. includes、indexOf、lastIndexOf
deepCloneArray.includes({ id: 5, name: 'jerry', age: 20 })
deepCloneArray.indexOf({ id: 5, name: 'jerry', age: 20 })
deepCloneArray.lastIndexOf({ id: 5, name: 'jerry', age: 20 })
-
功能:
includes判断数组是否包含某个元素,返回布尔值。indexOf返回元素的索引(左到右),(左到右)找不到返回-1。lastIndexOf返回元素的索引(右到左),找不到返回-1。
-
输出: 因为对象比较是引用类型,所以都返回
false和-1。 -
相似API:
find。区别在于:find可以用于对象属性比较。
-
使用场景: 当需要快速检查数组中是否包含某个简单值(如数字或字符串)。
7. splice、slice、toSpliced
deepCloneArray.splice(1, 1)
deepCloneArray.slice(1, 2)
const toSplicedArray = deepCloneArray.toSpliced(1, 1)
-
功能:
splice在原数组中删除或插入元素,会修改原数组。slice返回数组的一个片段,不修改原数组。toSpliced返回修改后的新数组,不改变原数组。
-
输出:
splice: 修改原数组。slice: 返回[ { id: 3, name: 'linlin', age: 17 } ]。toSpliced: 返回一个新的删除了元素的数组。
-
相似API:
pop和shift也删除元素,但只能在数组两端操作,而splice可在数组中间操作。 -
使用场景:
splice用于需要对数组进行增删改时,slice用于不修改原数组的情况下提取部分数据。
8. join
const joinedString = array.map(item => item.name).join(', ')
-
功能:
join将数组的所有元素连接成一个字符串,元素之间由指定的分隔符连接。 -
输出:
'tom, sam, linlin' -
使用场景: 当你需要将数组的内容转为字符串表示时,例如将用户名字组合为一段文本。
9. flat
flat 方法用于将多维数组按指定的深度扁平化为一维数组。
const flatArray = [1, [23, 45], 6, [7, [8, [9]]]];
// 将数组扁平化到指定的深度
const flatDepth2 = flatArray.flat(2);
// console.log(flatDepth2); // [ 1, 23, 45, 6, 7, 8, [9] ]
const flatInfinity = flatArray.flat(Infinity);
// console.log(flatInfinity); // [ 1, 23, 45, 6, 7, 8, 9 ]
-
功能:
flat: 将嵌套的数组扁平化到指定的深度。depth参数指定要扁平化的层级深度。Infinity表示将所有嵌套层级的数组都扁平化。
-
输出:
flat(depth):[ 1, 23, 45, 6, 7, 8, [9] ](将嵌套数组扁平化到深度为 2)flat(Infinity):[ 1, 23, 45, 6, 7, 8, 9 ](将所有嵌套层级的数组都扁平化)
-
相似 API:
reduce和concat。区别在于:reduce: 可以实现数组的扁平化,但需要手动实现。
-
使用场景:
flat: 当需要将多维数组扁平化为一维数组时使用。例如,处理多层嵌套的结构数据,便于进一步操作或展示。
10. every、some
const everyArray = array.every(item => item.age > 15)
const someArray = array.some(item => item.age === 16)
-
功能:
every检查数组中的每个元素是否都满足给定条件,返回布尔值。some检查数组中是否 至少有一个 元素满足条件,返回布尔值。
-
输出:
everyArray:truesomeArray:true
-
相似API:
filter和find。区别在于:every和some返回布尔值,而filter和find返回满足条件的元素。every要求所有元素都满足条件,而some只要求有一个元素满足。
-
使用场景:
every: 用于验证数组中所有元素是否符合某个条件,例如检查所有用户的年龄是否大于 15。some: 用于检查是否存在至少一个满足条件的元素,例如是否有用户的年龄为 16。
11. toSorted 和 sort
toSorted 和 sort 都可以用于排序数组,但有不同的行为和输出。
const toSortedArray = array.toSorted((a, b) => a.age - b.age);
// console.log(toSortedArray); // [ { id: 1, name: 'tom', age: 15 }, { id: 2, name: 'sam', age: 17 }, { id: 3, name: 'linlin', age: 17 } ]
const sortArray = array.sort((a, b) => b.age - a.age);
// console.log(sortArray); // [ { id: 2, name: 'sam', age: 17 }, { id: 3, name: 'linlin', age: 17 }, { id: 1, name: 'tom', age: 15 } ]
-
功能:
toSorted: 创建并返回一个新的排序数组,原数组保持不变。sort: 对原数组进行原地排序,修改原数组,并返回排序后的数组。
-
输出:
toSorted:[ { id: 1, name: 'tom', age: 15 }, { id: 2, name: 'sam', age: 17 }, { id: 3, name: 'linlin', age: 17 } ]sort:[ { id: 2, name: 'sam', age: 17 }, { id: 3, name: 'linlin', age: 17 }, { id: 1, name: 'tom', age: 15 } ]
-
相似 API:
reverse。区别在于:toSorted和sort用于排序数组,而reverse用于反转数组。
-
使用场景:
toSorted: 当需要保留原数组不变,同时获得一个新的排序数组时使用。sort: 当需要对原数组进行排序并修改原数组时使用。
12. reverse 和 toReversed
reverse 和 toReversed 都用于反转数组,但它们的行为和输出不同。
const reverseArray = array.reverse();
// console.log(reverseArray); // [ { id: 3, name: 'linlin', age: 17 }, { id: 2, name: 'sam', age: 17 }, { id: 1, name: 'tom', age: 15 } ]
const toReversedArray = array.toReversed();
// console.log(toReversedArray); // [ { id: 3, name: 'linlin', age: 17 }, { id: 2, name: 'sam', age: 17 }, { id: 1, name: 'tom', age: 15 } ]
-
功能:
reverse: 对原数组进行原地反转,修改原数组,并返回反转后的数组。toReversed: 创建并返回一个新的反转数组,原数组保持不变。
-
输出:
reverse:[ { id: 3, name: 'linlin', age: 17 }, { id: 2, name: 'sam', age: 17 }, { id: 1, name: 'tom', age: 15 } ]toReversed:[ { id: 3, name: 'linlin', age: 17 }, { id: 2, name: 'sam', age: 17 }, { id: 1, name: 'tom', age: 15 } ]
-
使用场景:
reverse: 当需要对原数组进行反转并修改原数组时使用。toReversed: 当需要保留原数组不变,同时获得一个新的反转数组时使用。
13. concat 和 扩展运算符 ...
concat 和扩展运算符 ... 都可以用于合并数组。
const concatArray = array.concat([{ id: 4, name: 'jerry', age: 18 }]);
// console.log(concatArray); // [ { id: 1, name: 'tom', age: 15 }, { id: 2, name: 'sam', age: 17 }, { id: 3, name: 'linlin', age: 17 }, { id: 4, name: 'jerry', age: 18 } ]
const spreadArray = [...array, { id: 4, name: 'jerry', age: 18 }];
// console.log(spreadArray); // [ { id: 1, name: 'tom', age: 15 }, { id: 2, name: 'sam', age: 17 }, { id: 3, name: 'linlin', age: 17 }, { id: 4, name: 'jerry', age: 18 } ]
-
功能:
concat方法用于连接两个或多个数组,不修改原数组,返回新的数组。- 扩展运算符
...通过展开数组元素,也可以实现数组合并。
-
输出:
concat:[ { id: 1, name: 'tom', age: 15 }, { id: 2, name: 'sam', age: 17 }, { id: 3, name: 'linlin', age: 17 }, { id: 4, name: 'jerry', age: 18 } ]spread:[ { id: 1, name: 'tom', age: 15 }, { id: 2, name: 'sam', age: 17 }, { id: 3, name: 'linlin', age: 17 }, { id: 4, name: 'jerry', age: 18 } ]
-
使用场景:
concat和...: 用于合并数组,适合不改变原数组的场景。
小技巧类
1. at
at 方法用于从数组中获取相对于数组末尾的元素。
const atArray = array.at(-1);
// console.log(atArray); // { id: 2, name: 'sam', age: 17 }
-
功能:
at方法允许使用正整数或负整数作为索引来访问数组的元素。正整数表示从数组的开头开始计数,负整数表示从数组的末尾开始计数。 -
输出:
{ id: 2, name: 'sam', age: 17 }(数组的最后一个元素) -
相似 API:
[](方括号索引)。区别在于:[]使用正整数索引直接访问数组元素,而负整数索引会导致[]返回undefined。at支持负整数索引,能够方便地从数组末尾获取元素。
-
使用场景: 用于获取数组末尾的元素,尤其是在不知道数组长度的情况下访问最后几个元素时非常方便。
2. flatMap
flatMap 方法用于将每个元素先映射到一个新数组,然后将所有这些数组合并成一个新的数组。
const flatMapArray = array.flatMap(item => item.age > 16 ? item.name : []).join('、');
// console.log(flatMapArray); // sam、linlin
-
功能:
flatMap: 将数组的每个元素映射到一个数组,然后将这些数组合并成一个新数组,最后返回这个新数组。适用于需要对数组进行映射和扁平化操作的场景。
-
输出:
flatMap:'sam、linlin'
-
相似 API:
filter和map。区别在于:map: 仅用于映射数组元素,通常生成的数组可能需要额外的扁平化步骤(如通过flat方法)。
-
使用场景:
flatMap: 当需要对数组元素进行映射,并且映射后的结果需要进行扁平化时使用。例如,从一组对象中提取符合条件的属性并合并成一个新数组。
3. reduce 和 reduceRight
reduce 和 reduceRight 都是 JavaScript 数组的方法,用于对数组进行迭代并产生一个最终的结果。它们的主要区别在于迭代的顺序不同。
const reduceArray = array.reduce((prev, curr) => {
curr.age += 2;
prev.push(curr);
return prev;
}, []);
const reduceRightArray = array.reduceRight((prev, curr) => {
curr.age -= 1;
prev.push(curr);
return prev;
}, []);
-
功能:
reduce遍历数组,从左到右地累加结果,并将累计结果传递给下一个元素reduceRight反之。常用于数组累加或构建新数组。 -
输出:
[ { id: 1, name: 'tom', age: 16 }, { id: 2, name: 'sam', age: 18 }, { id: 3, name: 'linlin', age: 18 } ][ { id: 3, name: 'linlin', age: 17 }, { id: 2, name: 'sam', age: 17 }, { id: 1, name: 'tom', age: 15 } ]
-
使用场景: 常用于累加、统计等复杂操作,如计算数组的总和或将数组转换为对象。
4. structuredClone
const deepCloneArray = structuredClone(array)
-
功能: 深拷贝数组,复制包括嵌套对象在内的所有数据,避免原数组变化影响克隆后的数组。
-
输出: 完全独立的深拷贝数组。
-
相似API:
Object.assign、JSON.stringify/JSON.parse。区别在于:structuredClone支持深度复制,包括复杂结构和引用类型。Object.assign只做浅拷贝,嵌套对象仍共享引用。JSON方法只能处理基本数据类型,不能处理函数或循环引用。
-
使用场景: 当你需要创建一个不受原数组影响的独立副本,且这个数组有深层嵌套对象时。
一般用不到(知道即可)
1. fill
fill 方法用于填充数组的指定部分,用新的值替换数组中的元素。
const fillArray = array.fill({ id: 9, name: 'lisa', age: 18 }, 0, 1);
// console.log(fillArray); // [ { id: 9, name: 'lisa', age: 18 }, { id: 9, name: 'lisa', age: 18 }, { id: 2, name: 'sam', age: 17 } ]
-
功能:
fill方法用指定的值填充数组的一部分或全部,可以设置填充的开始和结束位置。 -
输出:
[ { id: 9, name: 'lisa', age: 18 }, { id: 9, name: 'lisa', age: 18 }, { id: 2, name: 'sam', age: 17 } ](从索引0到1位置用{ id: 9, name: 'lisa', age: 18 }填充) -
相似 API:
splice。区别在于:fill用于替换数组元素的值,而splice可以插入、删除或替换数组中的元素。fill直接用指定值替换,而splice提供更多操作选项,如删除和插入元素。
-
使用场景: 用于初始化数组的部分内容或将数组中某一部分元素替换为相同的值,适合在需要批量修改数组数据时使用。
2. values, keys, entries
values, keys, 和 entries 方法用于获取数组的不同视图,它们都返回一个迭代器对象,支持 for...of 循环遍历。
const array = [
{ id: 1, name: 'tom', age: 15 },
{ id: 3, name: 'linlin', age: 17 },
{ id: 2, name: 'sam', age: 17 }
];
const valuesArray = array.values();
const keysArray = array.keys();
const entriesArray = array.entries();
for (let value of valuesArray) {
// console.log(value); // { id: 1, name: 'tom', age: 15 } { id: 3, name: 'linlin', age: 17 } { id: 2, name: 'sam', age: 17 }
}
for (let key of keysArray) {
// console.log(key); // 0 1 2
}
for (let [key, value] of entriesArray) {
// console.log(key, value); // 0 { id: 1, name: 'tom', age: 15 } 1 { id: 3, name: 'linlin', age: 17 } 2 { id: 2, name: 'sam', age: 17 }
}
-
功能:
values(): 返回一个包含数组值的迭代器。keys(): 返回一个包含数组索引的迭代器。entries(): 返回一个包含数组索引和对应值的迭代器。
-
输出:
values: 迭代器的每一项是数组中的值,例如{ id: 1, name: 'tom', age: 15 }。keys: 迭代器的每一项是数组中的索引,例如0, 1, 2。entries: 迭代器的每一项是一个包含索引和对应值的数组,例如[0, { id: 1, name: 'tom', age: 15 }]。
3. copyWithin 和 with
copyWithin 和 with 都是用于操作数组的方法,但它们的功能和用途不同。
const copyWithinArray = array.copyWithin(0, 2);
// console.log(copyWithinArray); // [ { id: 2, name: 'sam', age: 17 }, { id: 3, name: 'linlin', age: 17 }, { id: 2, name: 'sam', age: 17 } ]
const withArray = array.with(0, { id: 8, name: 'linda', age: 18 });
// console.log(withArray); // [ { id: 8, name: 'linda', age: 18 }, { id: 3, name: 'linlin', age: 17 }, { id: 2, name: 'sam', age: 17 } ]
-
功能:
copyWithin将数组中的部分内容复制到指定位置,覆盖目标位置的值。with方法用于更新数组中的指定位置的元素。
-
输出:
copyWithin:[ { id: 2, name: 'sam', age: 17 }, { id: 3, name: 'linlin', age: 17 }, { id: 2, name: 'sam', age: 17 } ](将数组从索引2开始的元素复制到索引0处)with:[ { id: 8, name: 'linda', age: 18 }, { id: 3, name: 'linlin', age: 17 }, { id: 2, name: 'sam', age: 17 } ](将索引0处的元素替换为{ id: 8, name: 'linda', age: 18 })
-
相似 API:
splice。区别在于:copyWithin是一个替换操作,复制并覆盖数组中的内容。splice可以插入、删除或替换元素。with主要用于更新指定位置的单个元素。
-
使用场景:
copyWithin: 用于局部数组数据的复制与覆盖,如根据现有数据进行部分填充或更新。with: 用于更新数组中的单个元素,如根据新数据修改指定索引的内容。
总结
本文主要梳理回顾了数组的方法,这环境,卷起来吧各位,地基打好解决问题的方式就多了,最后,阿lin祝大家都能找到好的工作(涨薪)啦
转载自:https://juejin.cn/post/7414295570192187418