Array数组中map,forEach和filter的区别

5 阅读3分钟

在 JavaScript 中,forEachfiltermap 是数组(Array)原型上非常常用的高阶函数(Higher-order Functions),它们都用于遍历数组,但目的、返回值和使用场景各不相同。下面详细说明它们的作用、区别和典型应用场景:


1. forEach

✅ 作用:

对数组的每个元素执行一次回调函数,常用于执行副作用操作(如打印、修改外部变量、发起请求等)。

🔁 返回值:

undefined(不返回新数组,也不改变原数组)

语法:

arr.forEach((element, index, array) => {
  /* ... */
});

应用场景:

  • 遍历数组并打印日志
  • 向服务器批量发送请求
  • 修改外部状态(如累加器、DOM 操作)

❌ 不能:

  • 中断循环(没有 break
  • 返回新数组

示例:

const numbers = [1, 2, 3];
numbers.forEach((n) => console.log(n * 2)); // 输出: 2, 4, 6

2. map

✅ 作用:

对数组中每个元素调用回调函数,并返回一个新数组,新数组的每个元素是回调函数的返回值。

🔁 返回值:

新数组(长度与原数组相同)

语法:

const newArray = arr.map((element, index, array) => {
  return transformedValue;
});

应用场景:

  • 数据转换(如把 ID 数组转为对象)
  • 格式化数据(如价格加单位、日期格式化)
  • React/Vue 中渲染列表前的数据映射

示例:

const names = ["alice", "bob"];
const upperNames = names.map((name) => name.toUpperCase());
// 结果: ['ALICE', 'BOb']

3. filter

✅ 作用:

筛选数组中满足条件的元素,返回一个新数组。

🔁 返回值:

新数组(包含所有使回调返回 true 的元素)

语法:

const filteredArray = arr.filter((element, index, array) => {
  return booleanCondition;
});

应用场景:

  • 搜索/过滤(如“只显示已激活用户”)
  • 去除无效值(如过滤掉 null0、空字符串)
  • 权限控制(如“只显示当前角色可访问的菜单”)

示例:

const scores = [85, 92, 78, 96];
const passed = scores.filter((score) => score >= 80);
// 结果: [85, 92, 96]

核心区别总结

方法是否返回新数组是否修改原数组主要用途能否链式调用
forEach❌(返回 undefined执行副作用(如打印、请求)
map转换每个元素
filter筛选符合条件的元素

✅ 这三个方法都不会修改原数组(除非你在回调中显式修改引用类型的内容)。


🔄 链式调用示例(常见组合)

const users = [
  { name: "Alice", age: 25, active: true },
  { name: "Bob", age: 30, active: false },
  { name: "Charlie", age: 35, active: true },
];

// 获取所有活跃用户的姓名(大写)
const activeNames = users
  .filter((user) => user.active)
  .map((user) => user.name.toUpperCase());

// 结果: ['ALICE', 'CHARLIE']

这种链式写法清晰、函数式、无副作用,是现代 JS 开发的推荐方式。


⚠ 注意事项

  • 不要在 map 中做副作用操作(如 console.log),这违背其“纯函数”设计初衷。
  • 如果只是想遍历而不返回结果,用 forEach;如果要生成新数据,优先用 map/filter
  • 性能上,for 循环更快,但在可读性和维护性上,这些高阶函数更优(除非性能敏感场景)。

一句话记忆

  • forEach做事(执行操作)
  • map变形(每个元素变个样)
  • filter挑人(留下符合条件的)