es6 map() 和 forEach 区别

Map  和  forEach  区别

.forEachmap的相同点

1.都是数组的方法+都是用来遍历数组

2.两个函数都有4个参数:匿名函数中可传3个参数item(当前项),index(当前项的索引),arr(原数组),还有一个可选参数this

3.匿名函数中的this默认是指向window

4.对空数组不会调用回调函数

5.不会改变原数组(某些情况下可改变)

 

Map

1.map接收后三个参数(1.当前值,2.当前值下标,3.原始数组[ ]

const arr = ['1', '2', '3'];

const cb = (str, i, origin) => 

{ console.log(`${i}: ${Number(str)} / ${origin}`); };

arr.map(cb);

Map单独作为回调函数使用

arr.map((str) => { console.log(Number(str)); })   //123

 

  1. Map会创建一个新数组,创建新空间,接受原始数组

1返回一个经过处理后的新数组,但不改变原数组

var a=[1,2,3,4,5]

var b=a.map((item)=>{

  return  item=item*2  //需要创建返回值接收值

})

console.log(a)//[1,2,3,4,5]

console.log(b)//[2,4,6,8,10]

2map中可改变原数组的情况和原理与forEach相同

 

forEach

1)没有返回值

var a=[1,2,3,4,5]

var b=a.forEach((item)=>{

  item=item*2

})

console.log(b)//undefined

//1.不能创建新数组,没有返回值

item的值并不是相应的原数组中的值,而是重新建立的一个新变量,值和原数组相同。

//简单来说forEach((item)=>{})

item是从a[]数组里面复制出来的与a[]中每一项值都一样的新变量,并不是原数组a[],

所以item改变仅改变item 复制出来的自己这个新变量,对原数组堆内存都没有影响,

2)可改变原数组的情况

var a=[1,2,3,4,5]

a.forEach(item)=>{

  item=item*2

}

console.log(a)//[1,2,3,4,5]

//2改变复制出的新变量

//数组中的对象的值也没有改变,是因为新创建的变量和原数组中的对象虽然指向同一个地址,但改变的是新变量的值,即新对象的值为2,原数组中的对象还是{num:1}

var a=[1,'1',{num:1},true]

a.forEach((item,index,arr)=>{

  item=2

})

console.log(a)//[1,'1',{num:1},true]

这里修改item值,依然没有修改原数组

var a=[1,'1',{num:1},true]

a.forEach((item,index,arr)=>{

  item.num=2

  item=2

})

console.log(a)//[1,'1',{num:2},true]

当修改数组中的对象的某个属性时,发现属性改变了。

//直接在数组上,  用.的方法 找到新对象指向的引用类型地址

由于对象是引用类型,新对象和旧对象指向的都是同一个引用地址,所以新对象把num变成了2,原数组中的对象也改变了。

为什么会这样呢?

这里就要引入栈(stack)内存和堆(heap)内存的概念了,

String,Number,Boolean,Undefined,Null是存在于栈内存中的,在栈内存中储存变量名及相应的值。

Object,Array,Function存在于堆内存中,在堆内存中储存变量名及引用位置。

想要修改原数组借助回调参数里的办法

var a = [1,2,3,4,5]

a.forEach((item, index, arr) => {

  arr[index] = item * 2

})

console.log(a)

// [2,4,6,8,10]

//在回调函数里改变arr的值,原数组改变了。

 

posted @ 2020-10-12 14:31  子不语~  阅读(2810)  评论(0编辑  收藏  举报