数组的各种JS方法汇总

76 阅读12分钟

一. 改变原数组的方法(9 个)

这类方法会直接修改原数组的内容 / 结构,使用时需注意副作用。

方法名称作用参数返回值示例
push(...items)向数组 末尾 添加一个或多个元素items(必填):要添加的元素(可多个)添加元素后数组的 新长度const arr = [1, 2]; const len = arr.push(3, 4); // len = 4,原数组变为 [1,2,3,4]
pop()删除数组 最后一个 元素-被删除的元素(数组为空时返回 undefinedconst 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()删除数组 第一个 元素-被删除的元素(数组为空时返回 undefinedconst 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-CNen-USoptions(可选):格式化配置(如数字保留 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 + flatcallback(必填):映射函数(参数: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 是最后一个元素)指定索引的元素(索引越界返回 undefinedconst 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;负数表示从倒数位置开始)找到返回索引,未找到返回 -1const arr = [1, 2, 3, 2]; arr.indexOf(2); // → 1(第一个2的索引) arr.indexOf(2, 2); // 从索引2开始找 → 3 arr.indexOf(4); // → -1(未找到)
lastIndexOf(searchElement[, fromIndex])从后往前查找元素,返回最后一个匹配的索引同 indexOffromIndex 默认数组长度 - 1)找到返回索引,未找到返回 -1const arr = [1, 2, 3, 2]; arr.lastIndexOf(2); // → 3(最后一个2的索引) arr.lastIndexOf(2, 1); // 从索引1往前找 → 1
includes(searchElement[, fromIndex])判断数组是否包含指定元素(比 indexOf 更直观)同 indexOf包含返回 true,否则返回 falseconst 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回调返回值组成的 新数组(长度与原数组一致)不改变原数组;回调必须有返回值(否则新数组元素为 undefinedconst 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 集合)或可迭代对象(如 SetStringmapFn(可选):映射函数(转换的同时处理元素) 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 undefinedmap 映射返回新数组,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(安全修改),优先使用更简洁高效。