map 与 forEach 区别
JavaScript 数组方法 map 和 forEach 的区别与使用场景
问题
map 和 forEach 都是数组遍历方法,它们有什么区别?分别在什么场景下使用?
解答
基本区别
const numbers = [1, 2, 3, 4, 5];
// forEach: 遍历数组,无返回值
const forEachResult = numbers.forEach((num) => {
return num * 2;
});
console.log(forEachResult); // undefined
// map: 遍历数组,返回新数组
const mapResult = numbers.map((num) => {
return num * 2;
});
console.log(mapResult); // [2, 4, 6, 8, 10]
链式调用
const numbers = [1, 2, 3, 4, 5];
// map 可以链式调用
const result = numbers
.map((num) => num * 2) // [2, 4, 6, 8, 10]
.filter((num) => num > 5) // [6, 8, 10]
.reduce((sum, num) => sum + num, 0); // 24
console.log(result); // 24
// forEach 无法链式调用,因为返回 undefined
使用场景
const users = [
{ name: 'Alice', age: 20 },
{ name: 'Bob', age: 25 },
{ name: 'Charlie', age: 30 },
];
// forEach: 执行副作用操作(打印、修改外部变量、DOM 操作等)
let totalAge = 0;
users.forEach((user) => {
console.log(user.name); // 打印每个用户名
totalAge += user.age; // 累加年龄
});
// map: 数据转换,生成新数组
const names = users.map((user) => user.name);
console.log(names); // ['Alice', 'Bob', 'Charlie']
const userCards = users.map((user) => ({
...user,
displayName: `${user.name} (${user.age}岁)`,
}));
console.log(userCards);
// [
// { name: 'Alice', age: 20, displayName: 'Alice (20岁)' },
// { name: 'Bob', age: 25, displayName: 'Bob (25岁)' },
// { name: 'Charlie', age: 30, displayName: 'Charlie (30岁)' }
// ]
性能差异
const largeArray = Array.from({ length: 1000000 }, (_, i) => i);
// 如果不需要返回值,forEach 更合适
// 因为 map 会创建新数组,占用额外内存
console.time('forEach');
largeArray.forEach((num) => {
// 执行某些操作
Math.sqrt(num);
});
console.timeEnd('forEach');
console.time('map');
largeArray.map((num) => {
// 执行某些操作
Math.sqrt(num);
});
console.timeEnd('map');
// map 会稍慢,因为需要创建和填充新数组
中断遍历
const numbers = [1, 2, 3, 4, 5];
// forEach 和 map 都无法用 break 中断
// 如果需要中断,使用 for...of 或 some/every
numbers.forEach((num) => {
if (num === 3) return; // 只能跳过当前迭代,不能中断整个循环
console.log(num);
});
// 输出: 1, 2, 4, 5
// 使用 some 实现中断
numbers.some((num) => {
if (num === 3) return true; // 返回 true 中断循环
console.log(num);
return false;
});
// 输出: 1, 2
关键点
- 返回值:
map返回新数组,forEach返回undefined - 用途:
map用于数据转换,forEach用于执行副作用 - 链式调用:
map支持链式调用,forEach不支持 - 性能:不需要返回值时用
forEach,避免map创建无用数组 - 中断:两者都无法用
break中断,需要中断时用for...of或some/every
目录