map和forEach的区别

map和forEach的区别


先总结下:

map和forEach区别是:
1.map有返回值而且必须return返回一个数组才行 ; 而forEach没有返回值可直接打印结果;
即:forEach()方法不会返回执行结果,而是undefined。也就是说,forEach()会修改原来的数组。而map()方法会得到一个新的数组并返回;

2.map因为返回数组所以可以链式操作,foreach不能;

3.map里可以用return ,而foreach里用return不起作用,foreach不能用break,会直接报错;
4. 总的来说 map 的速度大于forEach;

重要提示!!!!
①.使用map方法可以改变原数组?
当数组元素是基本数据类型时,map()方法不会改变原数组
当数组元素是引用类型时,map()方法会改变原数组!!

②.使用map方法可以改变原数组?—不会!!
map本身不会改变原数组任何属性

如果数组中的值是基本类型, 不改变;
如果是引用类型分两种情况:
1、没有修改形参元素的地址值, 只是修改形参元素内部的某些属性,会改变原数组;
(但这与map方法本身无关,map方法不会改变原数组,这属于强行访问到对象内部进行重新赋值)

2、直接修改整个元素对象时,无法改变原数组

使用场景
forEach适合于你并不打算改变数据的时候;
map()适用于你要改变数据值的时候。不仅仅在于它更快,而且返回一个新的数组。这样的优点在于你可以使用复合(composition)(map(), filter(), reduce()等组合使用);

下面直接上例子,比较两者区别:

基本数据类型:

1.map:

let arrA = [1, 2, 3];
let arrA1 = arrA.map(function (item, index, arr) {
      return item * 2;
  })
console.log(arrA, 'arrA为基本数据类型--原数组');
console.log(arrA1, 'arrA1为基本数据类型--map后的数据');


在这里插入图片描述

2.forEach:
数组包含的是基本数据类型a,那么在在使用forEach时候,形参b会在栈中拷贝一份原数组的指针与值,此时a与b是完全独立的数据,我们在修改b的值时是不会影响到a的值。

let arrA = [1, 2, 3];
let arrA2 = arrA.forEach(function (item, index, arr) {
     item = item * 2
 })
console.log(arrA, 'arrA为基本数据类型--原数组');
console.log(arrA2, 'arrA2为基本数据类型--forEach后的数据');

在这里插入图片描述
如何改变原数组中基本类型的值:
可以借助第二个参数index来改变数组

let arrA = [1, 2, 3];
let arrA2=arrA.forEach((item, index) => {
    arrA[index] = item * 2
})
console.log(arrA, 'arrA为基本数据类型--原数组');
console.log(arrA2, 'arrA2为基本数据类型--forEach后的数据');

在这里插入图片描述

引用数据类型:

1.map:

let arrB = [
   { name: 'a', age: 1 },
   { name: 'b', age: 2 },
];

let arrB1=arrB.map((item) => {
   item.age = 3;
   return item;
});

console.log(arrB, 'arrB为引用数据类型--原数组');
console.log(arrB1, 'arrB1为引用数据类型--map后的数据');;

在这里插入图片描述

原数组也变化了,怎么解决map方法导致的原数组变化的问题?
解决方法:

let arrB = [
     { name: 'a', age: 1 },
     { name: 'b', age: 2 },
 ];
  
 let arrB1=arrB.map((item) => {
     return {
         ...item,
         age:3
     };
 });

 console.log(arrB, 'arrB为引用数据类型--原数组');
 console.log(arrB1, 'arrB1为引用数据类型--map后的数据');

在这里插入图片描述

2.forEach:
数组包含的是引用数据类型a,那么在使用forEach的时候,形参b拷贝的是引用数据类型在栈中的地址,此时a和b都同时指向在一开始定义a时在堆中保存的数据,所以当我们修改b的数据,a的值也会改变,因为他们都是指向的堆中的同一数据。
(基本数据类型:栈中保存指针与值;引用数据类型:栈中保存指针,堆中保存值)

①、数组的元素是引用数据类型:(直接修改整个元素对象时,无法改变原数组)

let arrB = [
     { name: 'a', age: 1 },
     { name: 'b', age: 2 },
 ];
  
 let arrB2=arrB.forEach((item) => {
     item = {
         name: 'c',
         age: '3',
     };
 });

 console.log(arrB, 'arrB为引用数据类型--原数组');
 console.log(arrB2, 'arrB2为引用数据类型--forEach后的数据');

在这里插入图片描述

②.数组的元素是引用数据类型:(修改元素对象里的某个属性时,可以改变原数组)

let arrB = [
    { name: 'a', age: 1 },
    { name: 'b', age: 2 },
];
 
let arrB2=arrB.forEach((item) => {
    item.name = 'c';
});

console.log(arrB, 'arrB为引用数据类型--原数组');
console.log(arrB2, 'arrB2为引用数据类型--forEach后的数据');

在这里插入图片描述

參考:
https://blog.csdn.net/zhangwenok/article/details/124692883
https://blog.csdn.net/black_white_1/article/details/126710575

  • 15
    点赞
  • 90
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值