一. 改变原数组的方法(9 个)
这类方法会直接修改原数组的内容 / 结构,使用时需注意副作用。
| 方法名称 | 作用 | 参数 | 返回值 | 示例 |
|---|---|---|---|---|
| push(...items) | 向数组 末尾 添加一个或多个元素 | items(必填):要添加的元素(可多个) | 添加元素后数组的 新长度 | const arr = [1, 2]; const len = arr.push(3, 4); // len = 4,原数组变为 [1,2,3,4] |
| pop() | 删除数组 最后一个 元素 | - | 被删除的元素(数组为空时返回 undefined) | const arr = [1, 2, 3]; const delItem = arr.pop(); // delItem = 3,原数组变为 [1,2] |
| unshift(...items) | 向数组 开头 添加一个或多个元素 | items(必填):要添加的元素(可多个) | 添加元素后数组的 新长度 | const arr = [3, 4]; const len = arr.unshift(1, 2); // len = 4,原数组变为 [1,2,3,4] |
| shift() | 删除数组 第一个 元素 | - | 被删除的元素(数组为空时返回 undefined) | const arr = [1, 2, 3]; const delItem = arr.shift(); // delItem = 1,原数组变为 [2,3] |
| splice(start[, deleteCount[, ...items]]) | 删除、替换、插入元素(数组的「万能修改方法」) | start(必填):起始索引(负数表示从末尾倒数,如 -1 是最后一个元素)deleteCount(可选):要删除的元素个数(0 表示不删除); items(可选):要插入 / 替换的元素(删除后在 start 位置插入) | 被删除元素组成的数组(无删除时返回空数组) | const arr = [1, 2, 3, 4, 5]; arr.splice(2, 1); // 删除索引2的元素 → 原数组 [1,2,4,5],返回 [3] arr.splice(2, 0, 3); // 插入元素 → 原数组 [1,2,3,4,5],返回 [] arr.splice(1, 2, 'a', 'b'); // 替换元素 → 原数组 [1,'a','b',4,5],返回 [2,3] |
| sort([compareFunction]) | 对数组元素排序(默认按「字符串 Unicode 编码」排序) | compareFunction(可选):排序规则函数(a, b 为相邻元素); 返回负数:a 排在 b 前面; 返回正数:b 排在 a 前面 ; 返回 0:顺序不变 | 排序后的 原数组(不是新数组!) | const arr1 = [3, 1, 2]; arr1.sort(); // 默认排序 → 原数组 [1,2,3](数字侥幸正确,非数字会出错) const arr2 = [10, 2, 99]; arr2.sort((a, b) => a - b); // 数字升序 → [2,10,99] arr2.sort((a, b) => b - a); // 数字降序 → [99,10,2] const arr3 = [{ age: 20 }, { age: 18 }]; arr3.sort((a, b) => a.age - b.age); // 对象按属性排序 → [{age:18}, {age:20}] |
| reverse() | 反转数组元素的顺序 | - | 反转后的 原数组 | const arr = [1, 2, 3]; arr.reverse(); // 原数组变为 [3,2,1],返回 [3,2,1] |
| fill(value[, start[, end]]) | 用指定值填充数组(覆盖原有元素) | value(必填):填充的值start(可选):起始索引(默认 0)end(可选):结束索引(不包含,默认数组长度;负数表示倒数) | 填充后的 原数组 | const arr = [1, 2, 3, 4]; arr.fill(0); // 全填充 → [0,0,0,0] arr.fill(5, 1, 3); // 填充索引1-2 → [0,5,5,0] arr.fill(6, -2); // 从倒数第2个开始填充 → [0,5,6,6] |
| copyWithin(target[, start[, end]]) | 复制数组的一部分到同一数组的另一位置(覆盖原有元素) | - target(必填):复制到的目标索引 start(可选):复制的起始索引(默认 0) end(可选):复制的结束索引(不包含,默认数组长度) | 修改后的 原数组 | const arr = [1, 2, 3, 4, 5]; arr.copyWithin(2, 0, 2); // 复制索引0-1到索引2 → [1,2,1,2,5] arr.copyWithin(0, 3); // 复制索引3-4到索引0 → [2,5,1,2,5] |
二. 不改变原数组的方法(12 个)
这类方法不会修改原数组,而是返回新数组 / 字符串 / 值,安全无副作用。
| 方法名称 | 作用 | 参数 | 返回值 | 示例 |
|---|---|---|---|---|
| concat(...arrays) | 拼接两个或多个数组(合并数组) | arrays(可选):要拼接的数组 / 元素(单个元素也可直接传入) | 拼接后的 新数组 | const arr1 = [1, 2]; const arr2 = [3, 4]; const newArr = arr1.concat(arr2, 5, [6]); // 新数组 [1,2,3,4,5,6],原数组不变 |
| slice([start[, end]]) | 截取数组的一部分(切片) | start(可选):起始索引(默认 0;负数表示倒数) end(可选):结束索引(不包含,默认数组长度;负数表示倒数) | 截取部分组成的 新数组(原数组不变) | const arr = [1, 2, 3, 4, 5]; arr.slice(1, 3); // 截取索引1-2 → [2,3] arr.slice(-3); // 截取最后3个 → [3,4,5] arr.slice(2, -1); // 截取索引2到倒数第2个 → [3,4] |
| join([separator]) | 将数组元素拼接为字符串 | separator(可选):分隔符(默认 ",";传 "" 则无分隔符) | 拼接后的字符串 | const arr = [1, 2, 3]; arr.join(); // 默认为逗号 → "1,2,3" arr.join("-"); // 分隔符为横杠 → "1-2-3" arr.join(""); // 无分隔符 → "123" |
| toString() | 将数组转为字符串(等价于 join(",")) | - | 数组元素的字符串形式(用逗号分隔) | const arr = [1, "a", true]; arr.toString(); // → "1,a,true"(原数组不变) |
| toLocaleString([locales[, options]]) | 按本地化规则将数组转为字符串(支持数字、日期的本地化格式) | locales(可选):语言标签(如 zh-CN、en-US) options(可选):格式化配置(如数字保留 2 位小数) | 本地化后的字符串 | const arr = [1234.56, new Date()]; arr.toLocaleString("zh-CN", { maximumFractionDigits: 2 }); // → "1,234.56,2025/11/5 10:00:00"(数字千分位,日期中文格式) |
| flat([depth]) | 拍平数组(降低多维数组的维度) | depth(可选):拍平深度(默认 1;Infinity 表示拍平所有层级) | 拍平后的 新数组 | const arr = [1, [2, [3, [4]]]]; arr.flat(); // 拍平1层 → [1,2,[3,[4]]] arr.flat(2); // 拍平2层 → [1,2,3,[4]] arr.flat(Infinity); // 拍平所有层 → [1,2,3,4] |
| flatMap(callback[, thisArg]) | 先对数组元素执行 map 映射,再对结果执行 flat(1) 拍平(效率高于 map + flat) | callback(必填):映射函数(参数:item 元素、index 索引、array 原数组) thisArg(可选):callback 中 this 的指向 | 映射 + 拍平后的 新数组 | const arr = [1, 2, 3]; // 等价于 arr.map(x => [x*2]).flat(1) arr.flatMap(x => [x * 2]); // → [2,4,6] arr.flatMap(x => [x, x+1]); // → [1,2,2,3,3,4] |
| at(index) | 获取指定索引的元素(支持负索引,比 arr[index] 更灵活) | index(必填):索引(正数从开头,负数从末尾,如 -1 是最后一个元素) | 指定索引的元素(索引越界返回 undefined) | const arr = [1, 2, 3, 4]; arr.at(0); // → 1(等价于 arr[0]) arr.at(-1); // → 4(最后一个元素,arr[-1] 不支持) arr.at(10); // → undefined(越界) |
| indexOf(searchElement[, fromIndex]) | 从前往后查找元素,返回第一个匹配的索引 | searchElement(必填):要查找的元素(严格相等 === 匹配) fromIndex(可选):起始查找索引(默认 0;负数表示从倒数位置开始) | 找到返回索引,未找到返回 -1 | const arr = [1, 2, 3, 2]; arr.indexOf(2); // → 1(第一个2的索引) arr.indexOf(2, 2); // 从索引2开始找 → 3 arr.indexOf(4); // → -1(未找到) |
| lastIndexOf(searchElement[, fromIndex]) | 从后往前查找元素,返回最后一个匹配的索引 | 同 indexOf(fromIndex 默认数组长度 - 1) | 找到返回索引,未找到返回 -1 | const arr = [1, 2, 3, 2]; arr.lastIndexOf(2); // → 3(最后一个2的索引) arr.lastIndexOf(2, 1); // 从索引1往前找 → 1 |
| includes(searchElement[, fromIndex]) | 判断数组是否包含指定元素(比 indexOf 更直观) | 同 indexOf | 包含返回 true,否则返回 false | const arr = [1, 2, 3]; arr.includes(2); // → true arr.includes(4); // → false arr.includes(2, 3); // 从索引3开始找 → false |
| with(index, value)(ES2024 新增) | 修改数组指定索引的元素(不改变原数组,返回新数组) | index(必填):要修改的索引(支持负索引) value(必填):新值 | 修改后的 新数组(原数组不变) | const arr = [1, 2, 3]; const newArr = arr.with(1, 4); // 新数组 [1,4,3],原数组仍为 [1,2,3] arr.with(-1, 5); // → [1,2,5](修改最后一个元素) |
三. 遍历 / 迭代方法(14 个)
这类方法用于遍历数组元素,执行回调函数,核心是「处理每个元素」。
| 方法名称 | 作用 | 参数 | 返回值 | 特点 | 示例 |
|---|---|---|---|---|---|
| forEach(callback[, thisArg]) | 遍历数组,对每个元素执行回调(无返回值,仅用于副作用) | callback(必填):回调函数(参数:item 元素、index 索引、array 原数组) thisArg(可选):callback 中 this 的指向 | undefined | 无法用 break 中断遍历(除非抛异常);遍历空元素(稀疏数组)会跳过 | const arr = [1, 2, 3]; arr.forEach((item, index) => { console.log(索引${index}:${item}); // 依次输出 1、2、3 }); |
| map(callback[, thisArg]) | 遍历数组,对每个元素执行映射,返回新数组(「转换数组」常用) | 同 forEach | 回调返回值组成的 新数组(长度与原数组一致) | 不改变原数组;回调必须有返回值(否则新数组元素为 undefined) | const arr = [1, 2, 3]; const newArr = arr.map(item => item * 2); // 新数组 [2,4,6],原数组不变 const users = [{ name: "A" }, { name: "B" }]; const names = users.map(u => u.name); // 提取属性 → ["A", "B"] |
| filter(callback[, thisArg]) | 遍历数组,筛选出符合条件的元素,返回新数组(「过滤数组」常用) | 同 forEach(回调返回布尔值,true 保留元素) | 符合条件的元素组成的 新数组(长度 ≤ 原数组) | - | const arr = [1, 2, 3, 4, 5]; const evenArr = arr.filter(item => item % 2 === 0); // 筛选偶数 → [2,4] const users = [{ age: 18 }, { age: 25 }, { age: 16 }]; const adults = users.filter(u => u.age >= 18); // 筛选成年人 → [{age:18}, {age:25}] |
| some(callback[, thisArg]) | 判断数组是否「至少有一个」元素符合条件(「存在性判断」) | 同 forEach(回调返回布尔值) | true(有符合条件的元素)/ false(无) | 短路遍历(找到第一个符合条件的元素后立即停止) | const arr = [1, 2, 3]; arr.some(item => item > 2); // → true(3>2) arr.some(item => item > 5); // → false |
| every(callback[, thisArg]) | 判断数组是否「所有」元素都符合条件(「全量判断」) | 同 forEach(回调返回布尔值) | true(所有元素符合)/ false(至少一个不符合) | 短路遍历(找到第一个不符合条件的元素后立即停止) | const arr = [2, 4, 6]; arr.every(item => item % 2 === 0); // → true(全是偶数) arr.every(item => item > 3); // → false(2≤3) |
| find(callback[, thisArg]) | 查找数组中「第一个」符合条件的元素 | 同 forEach(回调返回布尔值) | 找到返回元素,未找到返回 undefined | 短路遍历;支持查找引用类型(如对象) | const users = [{ id: 1 }, { id: 2 }, { id: 3 }]; const user = users.find(u => u.id === 2); // → { id: 2 } users.find(u => u.id === 4); // → undefined |
| findIndex(callback[, thisArg]) | 查找数组中「第一个」符合条件的元素的索引 | 同 forEach(回调返回布尔值) | 找到返回索引,未找到返回 -1 | 短路遍历;比 indexOf 灵活(支持复杂条件) | const arr = [1, 3, 5, 7]; arr.findIndex(item => item > 4); // → 2(第一个>4的元素是5,索引2) arr.findIndex(item => item < 0); // → -1 |
| findLast(callback[, thisArg])(ES2022 新增) | 从后往前查找「最后一个」符合条件的元素 | 同 find | 找到返回元素,未找到返回 undefined | - | const arr = [1, 3, 5, 7]; arr.findLast(item => item > 4); // → 7(最后一个>4的元素) |
| findLastIndex(callback[, thisArg])(ES2022 新增) | 从后往前查找「最后一个」符合条件的元素的索引 | 同 findIndex | 找到返回索引,未找到返回 -1 | - | const arr = [1, 3, 5, 7]; arr.findLastIndex(item => item > 4); // → 3(7的索引) |
| reduce(callback(accumulator, currentValue, currentIndex, array)[,initialValue]) | 遍历数组,将元素「累积」为一个值(「汇总数组」常用,如求和、求对象) | callback(必填):累积函数,参数: accumulator:累加器(上一次回调的返回值) currentValue:当前元素 currentIndex:当前索引 array:原数组 initialValue(可选):累加器初始值(无则用数组第一个元素,且从索引 1 开始遍历) | 最终累积的结果 | - | const arr = [1, 2, 3, 4]; // 求和(带初始值0) const sum = arr.reduce((acc, curr) => acc + curr, 0); // → 10 // 求对象属性总和 const users = [{ age: 18 }, { age: 25 }]; const totalAge = users.reduce((acc, u) => acc + u.age, 0); // → 43 // 数组转对象(id为key) const obj = users.reduce((acc, u) => ({ ...acc, [u.id]: u }), {}); |
| reduceRight(callback[, initialValue]) | 同 reduce,但遍历顺序为「从后往前」 | - | - | - | const arr = [1, 2, 3]; arr.reduceRight((acc, curr) => acc + curr, 0); // → 6(3+2+1) |
| entries() | 返回数组的「键值对迭代器」(索引 + 元素) | - | 迭代器对象(可通过 for...of 遍历) | - | const arr = [1, 2, 3]; const iterator = arr.entries(); for (const [index, item] of iterator) { console.log(index, item); // 0 1 → 1 2 → 2 3 } |
| keys() | 返回数组的「索引迭代器」 | - | 迭代器对象 | - | const arr = [1, 2, 3]; for (const key of arr.keys()) { console.log(key); // 0 → 1 → 2 } |
| values() | 返回数组的「元素迭代器」 | - | 迭代器对象 | - | const arr = [1, 2, 3]; for (const value of arr.values()) { console.log(value); // 1 → 2 → 3 } |
四. 静态方法(4 个)
数组构造函数 Array 上的方法,无需实例化即可调用。
| 方法名称 | 作用 | 参数 | 返回值 | 对比 | 示例 |
|---|---|---|---|---|---|
| Array.from(arrayLike[, mapFn[, thisArg]]) | 将「类数组对象」或「可迭代对象」转为真正的数组 | arrayLike(必填):类数组(如 arguments、DOM 集合)或可迭代对象(如 Set、String) mapFn(可选):映射函数(转换的同时处理元素) thisArg(可选):mapFn 中 this 的指向 | 转换后的新数组 | - | // 类数组转数组 const arrayLike = { 0: 1, 1: 2, length: 2 }; Array.from(arrayLike); // → [1,2] // 字符串转数组 Array.from("abc"); // → ["a","b","c"] // Set转数组(去重) Array.from(new Set([1, 2, 2, 3])); // → [1,2,3] // 转换+映射 Array.from(arrayLike, x => x * 2); // → [2,4] |
| Array.of(...elements) | 创建一个包含指定元素的数组(解决 new Array() 的怪异行为) | elements(可选):要创建数组的元素 | 新数组 | new Array(3) 会创建长度为 3 的空数组,而 Array.of(3) 创建 [3] | Array.of(1, 2, 3); // → [1,2,3] Array.of(5); // → [5] Array.of(); // → [](无参数返回空数组) |
| Array.isArray(value) | 判断一个值是否为数组(比 typeof 更准确) | value(必填):要判断的值 | true(是数组)/ false(不是) | --- | Array.isArray([1,2]); // → true Array.isArray("12"); // → false Array.isArray({ length: 2 }); // → false |
| Array.count(array, callback)(ES2023 新增) | 统计数组中符合条件的元素个数(等价于 filter(callback).length,但效率更高) | array(必填):要统计的数组 callback(必填):判断函数(参数:item 元素、index 索引、array 原数组) | 符合条件的元素个数 | --- | const arr = [1, 2, 3, 4, 5]; Array.count(arr, item => item % 2 === 0); // → 2(偶数个数) const users = [{ age: 18 }, { age: 25 }, { age: 18 }]; Array.count(users, u => u.age === 18); // → 2 |
五. 常见方法对比(避坑重点)
| 方法 | 改变原数组 | 返回值类型 | 核心区别 |
|---|---|---|---|
slice vs splice | 否 vs 是 | 新数组 vs 被删元素数组 | slice 截取不修改,splice 万能修改 |
map vs forEach | 否 vs 否 | 新数组 vs undefined | map 映射返回新数组,forEach 仅遍历 |
some vs every | 否 vs 否 | 布尔值 vs 布尔值 | some 任意符合,every 全部符合 |
indexOf vs findIndex | 否 vs 否 | 索引 vs 索引 | indexOf 按值匹配,findIndex 按条件匹配 |
push vs unshift | 是 vs 是 | 新长度 vs 新长度 | push 尾部添加,unshift 头部添加 |
六. 总结
- 改变原数组:优先用
push/pop(尾部操作效率高),复杂修改用splice,排序用sort。 - 不改变原数组:合并用
concat,截取用slice,拍平用flat/flatMap,修改用with。 - 遍历处理:转换用
map,筛选用filter,汇总用reduce,判断用some/every,查找用find/findIndex。 - ES6+ 新增:
at(负索引)、flat(拍平)、count(统计)、findLast(反向查找)、with(安全修改),优先使用更简洁高效。