JavaScript数组常用方法大全:增删改查与遍历全解析

210 阅读7分钟

大家好,今天我们来聊一个前端开发中天天打交道的“老朋友”——JavaScript数组。数组作为最基础的数据结构之一,在实际开发中无处不在。无论是处理用户列表、商品数据,还是做复杂的状态管理,都离不开它。

而JS为数组提供了丰富的方法,掌握这些方法不仅能提升编码效率,还能写出更优雅、更易维护的代码。今天我们就来系统地梳理一下数组的常用操作方法,按 增、删、改、查、遍历 五大类来分类讲解,保证你看完后对数组有更全面的理解!


✅ 一、怎么往数组里“加”东西?—— 增(Add)

1. push():尾部添加

最常用的添加方法,在数组末尾添加一个或多个元素,并返回新长度。

const arr = [1, 2];
arr.push(3, 4); // [1, 2, 3, 4]

✅ 特点:改变原数组,返回的是新长度,不是新数组。


2. unshift():头部添加

push 相反,在数组开头插入元素

const arr = [2, 3];
arr.unshift(1); // [1, 2, 3]

⚠️ 注意:unshift 会重新索引整个数组,性能比 push 差,尤其数组大时慎用。


3. splice(start, deleteCount, ...items):万能插入/删除

这是一个“瑞士军刀”级的方法,既能删也能增。要实现“插入”,只需设置 deleteCount 为 0。

const arr = [1, 4];
arr.splice(1, 0, 2, 3); // 在索引1处插入2和3
// arr 变成 [1, 2, 3, 4]

✅ 灵活强大,但稍复杂,适合精确控制插入位置。


4. concat():拼接出新数组

如果你不想修改原数组,想生成一个新数组concat 就派上用场了。

const arr1 = [1, 2];
const arr2 = [3, 4];
const newArr = arr1.concat(arr2); // [1, 2, 3, 4]

✅ 返回新数组,不改变原数组,适合函数式编程。


5. Array.of()Array.from():创建新数组

虽然不是直接“添加”,但它们是创建数组的好帮手:

  • Array.of(1, 2, 3)[1, 2, 3]
  • Array.from('abc')['a', 'b', 'c'](类数组转数组)
  • Array.from([1, 2], x => x * 2)[2, 4](带 map 功能)

✅ 特别适合从类数组对象(如 arguments、DOM NodeList)创建真正的数组。


❌ 二、怎么“删”掉数组里的元素?—— 删(Remove)

1. pop():弹出最后一个

删除并返回数组最后一个元素。

const arr = [1, 2, 3];
arr.pop(); // 返回 3,arr 变成 [1, 2]

✅ 常用于栈结构操作。


2. shift():去掉第一个

删除并返回第一个元素。

const arr = [1, 2, 3];
arr.shift(); // 返回 1,arr 变成 [2, 3]

⚠️ 同样会重排索引,性能开销大。


3. splice():精准删除

指定从哪个位置开始,删几个。

const arr = [1, 2, 3, 4];
arr.splice(1, 2); // 从索引1开始删2个 → [1, 4]

✅ 最灵活的删除方式,支持插入+删除组合。


4. slice(start, end):切片(其实是“查”但常被误认为“删”)

注意!slice 不会改变原数组,而是返回一个新数组片段。

const arr = [1, 2, 3, 4];
const sub = arr.slice(1, 3); // [2, 3]
// arr 还是 [1, 2, 3, 4]

✅ 常用于“复制”部分元素,比如实现分页、截取前N项等。


🛠️ 三、怎么“改”变数组内容?—— 改(Modify)

1. splice() 再次登场:替换元素

不仅可以删和增,还能实现“替换”。

const arr = [1, 2, 3];
arr.splice(1, 1, 'x'); // 删除1个,插入'x' → [1, 'x', 3]

✅ 实现局部更新的利器。


2. sort(compareFn):排序

对数组进行原地排序(会改变原数组)。

[3, 1, 2].sort(); // [1, 2, 3]
// 自定义排序:按长度排字符串
// 创建一个变量来存储数组
const myArray = ['a', 'ccc', 'bb'];
// 对变量调用sort方法
myArray.sort((a, b) => a.length - b.length);
// 输出排序后的数组
console.log(myArray);
//[ 'a', 'bb', 'ccc' ]

⚠️ 注意:默认按字符串Unicode排序,数字排序一定要传 compareFn


3. reverse():反转数组

把数组顺序倒过来。

[1, 2, 3].reverse(); // [3, 2, 1]

✅ 原地反转,常用于倒序展示。


4. fill(value, start?, end?):填充统一值

把一段区间全部填成某个值。

new Array(5).fill(0); // [0, 0, 0, 0, 0]
[1, 2, 3, 4].fill('x', 1, 3); // [1, 'x', 'x', 4]

✅ 初始化数组或批量赋值很方便。


5. copyWithin(target, start, end?):内部复制

把数组内部某段内容复制到另一个位置。

[1, 2, 3, 4, 5].copyWithin(0, 3); // 把索引3开始的复制到0 → [4, 5, 3, 4, 5]

✅ 小众但有趣,适合特定算法场景。


🔍 四、怎么“查”找数组中的元素?—— 查(Search)

1. indexOf(item)lastIndexOf(item)

查找元素的索引位置,前者从前往后,后者从后往前。

const arr = [1, 2, 3, 2];
arr.indexOf(2);      // 1
arr.lastIndexOf(2);  // 3

✅ 找不到返回 -1,适合简单查找。


2. includes(item):是否存在?

判断数组是否包含某个值,返回 true/false

[1, 2, 3].includes(2); // true

✅ 比 indexOf !== -1 更语义化,推荐使用。


3. find(callback)findIndex(callback)

按条件查找第一个匹配的元素或其索引。

const users = [{id: 1, name: 'Alice'}, {id: 2, name: 'Bob'}];
users.find(u => u.id === 2);     // {id: 2, name: 'Bob'}
users.findIndex(u => u.name === 'Alice'); // 0

✅ 适合对象数组查找,非常实用!


4. findLast()findLastIndex()(ES2023)

从末尾开始查找第一个匹配项。

[1, 2, 3, 2].findLastIndex(x => x === 2); // 3

✅ 新增方法,填补了“反向查找”的空白。


🔁 五、怎么“遍历”数组?—— 遍历(Iterate)

这部分是数组操作的核心,也是面试常考点!

1. forEach(callback):简单遍历

执行一个函数对每个元素,不返回新数组

[1, 2, 3].forEach(console.log);

⚠️ 注意:不能中途 breakcontinue,除非用 try/catch 抛异常(不推荐):

try {
  arr.forEach(item => {
    if (item === 5) throw new Error('stop');
  });
} catch {}

✅ 建议:如果不需要返回值,用 forEach 更语义清晰。


2. map(callback):映射成新数组

对每个元素执行函数,返回一个新数组

[1, 2, 3].map(x => x * 2); // [2, 4, 6]

✅ 支持链式调用,如 .map().filter().sort(),是函数式编程的基石。

📌 map vs forEach

对比项mapforEach
返回值新数组undefined
是否改变原数组
链式调用✅ 可以❌ 不能
性能稍慢(创建新数组)稍快(无返回)
使用场景需要转换数据结构仅执行副作用(如打印)

3. filter(callback):筛选符合条件的元素

返回一个新数组,只包含满足条件的元素。

[1, 2, 3, 4].filter(x => x > 2); // [3, 4]

✅ 常用于搜索、过滤列表。


4. reduce(callback, initialValue):累计器

将数组“压缩”成一个值,功能极其强大。

[1, 2, 3].reduce((acc, cur) => acc + cur, 0); // 6

✅ 可实现:求和、扁平化、统计、对象分组等高级操作。


5. some()every():条件判断

  • some():是否有至少一个元素满足条件?
  • every():是否所有元素都满足条件?
[1, 2, 3].some(x => x > 2);  // true
[1, 2, 3].every(x => x > 0); // true

✅ 适合做“存在性”或“全量”校验,比如表单验证。


6. 其他实用方法

flat(depth):扁平化多维数组

[1, [2, 3], [4, [5]]].flat(2); // [1, 2, 3, 4, 5]

flatMap(callback):先 map 再 flat

['a b', 'c d'].flatMap(str => str.split(' ')); // ['a', 'b', 'c', 'd']

✅ 适合处理“一对多”映射后的扁平化。


🎯 总结:一张表帮你理清思路

类别方法是否改变原数组是否返回新数组典型用途
push, unshift, splice✅ 是❌ 否添加元素
concat, Array.from/of❌ 否✅ 是创建新数组
pop, shift, splice✅ 是❌ 否删除元素
slice❌ 否✅ 是截取片段
sort, reverse, fill, copyWithin, splice✅ 是❌ 否修改内容
indexOf, includes, find, findIndex❌ 否❌ 否(返回索引/元素)查找
遍历forEach❌ 否❌ 否执行副作用
map, filter, flatMap❌ 否✅ 是转换/筛选
reduce❌ 否✅ 是(单值)累计计算
some, every❌ 否✅ 是(布尔)条件判断

💡 最后的小建议

  1. 能用 for...of 或普通 for 循环时,性能最好,尤其是大数据量。
  2. 函数式方法(map/filter/reduce)更优雅、可读性强,适合处理逻辑转换。
  3. 避免滥用 splice 修改大数组,性能较差。
  4. 优先使用 const + 不变操作(如 mapfilter),减少副作用。

新方法的兼容性提醒

  • findLast() / findLastIndex()(ES2023)

  • flat() / flatMap()(ES2019)

    这些方法在老旧浏览器(特别是 IE 和早期的移动端 WebView)是不支持的。 需注意兼容性,可用 polyfill 或 Babel 转译。


希望这篇文章能帮你系统梳理JS数组的常用方法,下次写代码时,再也不用翻文档啦!