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
:1
findLastArray
:{ 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
:true
someArray
: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