forEach和map有什么区别

What is the big difference between forEach and map?

本文关键字:什么 区别 map forEach      更新时间:2023-09-26

这里有一些我不明白的地方。map函数,我几天前刚刚了解到,它应该是一个神奇的函数,如果我发现它的用途,它将改变我编写代码的方式。但我仍然看不出它与forEach有什么不同。唯一的区别是传递给map的函数将当前元素替换为return值。但forEach也可以做到这一点,这意味着map只是forEach的一个不太通用的版本。

MDN示例:

var numbers = [1, 4, 9];
var roots = numbers.map(Math.sqrt);
// roots is now [1, 2, 3], numbers is still [1, 4, 9]

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map

好吧,我想很酷吧?

我可以用forEach:做到这一点

var numbers = [1, 4, 9];
var roots = numbers.forEach(function(el){el=Math.sqrt(el);});
// roots is now [1, 2, 3], numbers is still [1, 4, 9]

其他示例:

var kvArray = [{key:1, value:10}, {key:2, value:20}, {key:3, value: 30}];
var reformattedArray = kvArray.map(function(obj){ 
   var rObj = {};
   rObj[obj.key] = obj.value;
   return rObj;
});
// reformattedArray is now [{1:10}, {2:20}, {3:30}], 
// kvArray is still [{key:1, value:10}, {key:2, value:20}, {key:3, value: 30}]

我可以用forEach做到这一点,它看起来几乎一模一样。

map有什么优点?在forEach不工作的情况下,它工作得非常好的例子是什么?

区别在于forEach"在数组上迭代"和map"在数组中迭代并返回结果"

var numbers = [1, 4, 9];
var roots = numbers.forEach(Math.sqrt);
// roots is undefined, numbers is still [1, 4, 9]
var roots = numbers.map(Math.sqrt);
// roots is [1, 2, 3], numbers is still [1, 4, 9]

map有什么优点?它使您的代码保持小型和智能,因为您不需要为内置函数定义匿名函数。

var numbers = [1, 4, 9];
var roots = [];
numbers.forEach(function(val){ roots.push( Math.sqrt(val) ); });
// roots is now [1, 2, 3], numbers is still [1, 4, 9]

返回结果(并非双关语)的价值在您现有的示例中得到了证明。。。

var kvArray = [{key:1, value:10}, {key:2, value:20}, {key:3, value: 30}];
var reformattedArray = kvArray.map(function(obj){ // <---------------- map
   var rObj = {};
   rObj[obj.key] = obj.value;
   return rObj;
});
// reformattedArray is now [{1:10}, {2:20}, {3:30}], 
// kvArray is still [{key:1, value:10}, {key:2, value:20}, {key:3, value: 30}]
var kvArray = [{key:1, value:10}, {key:2, value:20}, {key:3, value: 30}];
var reformattedArray = kvArray.forEach(function(obj){ // <---------------- forEach
   var rObj = {};
   rObj[obj.key] = obj.value;
   return rObj;
});
// reformattedArray is now undefined, 
// kvArray is still [{key:1, value:10}, {key:2, value:20}, {key:3, value: 30}]

地图

map对一个列表进行迭代并返回一个新列表,而不更改任何其他内容。它不会更改原始列表。它没有副作用。使用map,您可以获得一个与基元一起工作的普通函数,并提升该函数,以便它可以与这些基元的列表一起工作:

const map = (f, xs) => xs.map(x => f(x));
const sqr = x => x * x;
let xs = [1,2,3];
let x = 3;
sqr(x); // 9
sqr(xs); // Error
let ys = map(sqr, xs); // [1,4,9]
xs; // [1,2,3]

该示例说明了map如何在xs的上下文中提升sqr,以便它可以对xs的元素进行平方。通过这种方式,您可以重用数组的普通函数。

对于每个

forEach没有结果值。没有任何结果值的函数是无用的,除非它有一些副作用。因此,forEach必须对其迭代的元素应用副作用,才能做一些有意义的事情:

let ys = xs.forEach(sqr); // undefined
xs; // [1,2,3]
// without side effects, nothing has happened
const sqrWithSideEffect = (x, idx, arr) => arr[idx] = x * x; // ugly, isn't it?
xs.forEach(sqrWithSideEffect); // 
xs; // [1,4,9]; // side effect: destructive update of xs

结论forEach来自命令式编程,map来自函数式编程。两者都代表着相反的范式。因此,如果你真的想了解这两个函数之间差异的后果,你必须了解这两种编程范式之间的差异。

forEach vs.Map高阶阵列方法

const arr = [1,2,3]
const arr2 = [...arr,4,5]//see spread operator grepper answer for [...arr]
//the forEach doesn't return anything, it just loops through the array
arr2.forEach(function(item) {
  console.log(item + ' of ' + arr2.length)
})
//map allows us to return an array and store it into a new array
const arr3 = arr2.map(function(item) {
  //after performing some operation on all the objects of the array
  //we can then return all those values into a new array
  return item * 2
})
console.log(arr3)

Chack it