JavaScript 数组方法可按「是否修改原数组」核心分为 修改原数组(变异方法) 和 不修改原数组(非变异方法) 两大类,以下是全量方法的作用、是否改原数组及示例,附清晰分类和总结:
一、修改原数组的方法(变异方法)
这类方法会直接改变原数组的内容 / 结构,返回值多为新长度、被删除元素或修改后的数组(但核心是原数组已变)。
| 方法名 | 核心作用 | 是否修改原数组 | 示例 |
|---|---|---|---|
push(...items) | 向数组末尾添加 1 个 / 多个元素,返回新数组长度 | ✅ 是 | const arr = [1]; arr.push(2); // arr → [1,2],返回 2 |
pop() | 删除数组最后一个元素,返回被删除的元素 | ✅ 是 | const arr = [1,2]; arr.pop(); // arr → [1],返回 2 |
shift() | 删除数组第一个元素,返回被删除的元素 | ✅ 是 | const arr = [1,2]; arr.shift(); // arr → [2],返回 1 |
unshift(...items) | 向数组开头添加 1 个 / 多个元素,返回新数组长度 | ✅ 是 | const arr = [2]; arr.unshift(1); // arr → [1,2],返回 2 |
splice(start, delCount, ...add) | 删除 / 插入 / 替换元素(最灵活的修改方法),返回被删除的元素数组 | ✅ 是 | const arr = [1,2,3]; arr.splice(1,1,4); // arr → [1,4,3],返回 [2] |
sort([compareFn]) | 对数组排序(默认按字符串 Unicode 码点),返回排序后的数组 | ✅ 是 | const arr = [3,1,2]; arr.sort((a,b)=>a-b); // arr → [1,2,3] |
reverse() | 反转数组元素顺序,返回反转后的数组 | ✅ 是 | const arr = [1,2]; arr.reverse(); // arr → [2,1] |
fill(value, start, end) | 用指定值填充数组指定范围(左闭右开),返回填充后的数组 | ✅ 是 | const arr = [1,2,3]; arr.fill(0,1,2); // arr → [1,0,3] |
copyWithin(target, start, end) | 复制指定范围元素到目标位置,返回修改后的数组 | ✅ 是 | const arr = [1,2,3,4]; arr.copyWithin(0,2); // arr → [3,4,3,4] |
二、不修改原数组的方法(非变异方法)
这类方法仅返回新值 / 新数组,原数组始终保持不变(核心:只读不写)。
| 方法名 | 核心作用 | 是否修改原数组 | 示例 |
|---|---|---|---|
concat(...arrays) | 合并多个数组 / 值,返回新数组 | ❌ 否 | [1].concat([2]); // 返回 [1,2],原数组 [1] 不变 |
slice(start, end) | 截取数组指定范围(左闭右开),返回新数组 | ❌ 否 | [1,2,3].slice(1,2); // 返回 [2],原数组不变 |
join([sep]) | 将数组元素拼接为字符串(默认逗号分隔),返回字符串 | ❌ 否 | [1,2].join('-'); // 返回 "1-2",原数组不变 |
toString() | 转为字符串(等价于 join(',')),返回字符串 | ❌ 否 | [1,2].toString(); // 返回 "1,2" |
indexOf(val, from) | 查找元素首次出现的索引,找不到返回 -1,返回数字 | ❌ 否 | [1,2,3].indexOf(2); // 返回 1 |
lastIndexOf(val, from) | 查找元素最后出现的索引,找不到返回 -1,返回数字 | ❌ 否 | [1,2,2].lastIndexOf(2); // 返回 2 |
includes(val, from) | 判断数组是否包含指定元素,返回布尔值 | ❌ 否 | [1,2].includes(3); // 返回 false |
find(callback) | 查找第一个满足回调条件的元素,找不到返回 undefined | ❌ 否 | [1,2,3].find(item => item>1); // 返回 2 |
findIndex(callback) | 查找第一个满足回调条件的元素索引,找不到返回 -1 | ❌ 否 | [1,2,3].findIndex(item => item>1); // 返回 1 |
filter(callback) | 过滤出满足回调条件的元素,返回新数组 | ❌ 否 | [1,2,3].filter(item => item>1); // 返回 [2,3] |
map(callback) | 遍历数组,每个元素经回调处理后返回新值,组成新数组 | ❌ 否 | [1,2].map(item => item*2); // 返回 [2,4] |
reduce(callback, init) | 归并 / 累加,将数组转为单个值(从左到右),返回最终值 | ❌ 否 | [1,2,3].reduce((sum, item)=>sum+item, 0); // 返回 6 |
reduceRight(callback) | 归并 / 累加(从右到左),其余同 reduce | ❌ 否 | [1,2,3].reduceRight((sum, item)=>sum+item, 0); // 返回 6 |
flat(depth) | 扁平化数组(默认深度 1),返回新数组 | ❌ 否 | [1,[2,[3]]].flat(2); // 返回 [1,2,3] |
flatMap(callback) | 先 map 再 flat(1),返回新数组 | ❌ 否 | [1,2].flatMap(item=>[item, item*2]); // 返回 [1,2,2,4] |
entries() | 返回数组迭代器(键值对:[索引, 值]) | ❌ 否 | [1,2].entries(); // 迭代器:{0: [0,1], 1: [1,2]} |
keys() | 返回数组索引迭代器 | ❌ 否 | [1,2].keys(); // 迭代器:{0:0, 1:1} |
values() | 返回数组值迭代器 | ❌ 否 | [1,2].values(); // 迭代器:{0:1, 1:2} |
三、特殊遍历方法:forEach
-
作用:遍历数组,为每个元素执行回调函数,无返回值(始终返回
undefined)。 -
是否修改原数组:方法本身不修改,但回调内可手动修改原数组(如
arr[index] = 新值)。 -
示例:
js
const arr = [1,2]; // 方法本身不改,但回调手动改原数组 arr.forEach((item, index) => { arr[index] = item * 2; }); console.log(arr); // [2,4]
四、Array 静态方法(类级方法)
挂载在 Array 类上,用于创建数组,不修改任何原对象,返回新数组:
| 方法名 | 核心作用 | 是否修改原对象 |
|---|---|---|
Array.from(iter) | 将类数组 / 可迭代对象(如 arguments、字符串)转为数组,返回新数组 | ❌ 否 |
Array.of(...args) | 创建数组(解决 new Array 的坑:new Array(2) 是长度 2 的空数组,Array.of(2) 是 [2]) | ❌ 否 |
核心总结
| 类型 | 核心特征 | 典型方法 |
|---|---|---|
| 修改原数组 | 直接改变原数组结构 / 值 | push/pop/splice/sort/reverse |
| 不修改原数组 | 返回新值 / 新数组,原数组不变 | map/filter/slice/concat/reduce |
| 遍历方法 | 仅执行回调,本身不修改原数组 | forEach(回调可手动改) |
注意点
- sort 排序陷阱:默认按字符串 Unicode 排序,数值排序需传比较函数:
arr.sort((a,b) => a-b)(升序)、arr.sort((a,b) => b-a)(降序)。 - splice 灵活性:
splice(start, 0, val)是插入元素,splice(start, 1)是删除元素,splice(start, 1, val)是替换元素。 - 不可变编程:如需避免修改原数组,优先用
map/filter/slice/concat等,而非push/splice等变异方法。