区别
1.map有返回值,return一个新数组;forEach没有返回值(不会返回执行的结果)
2.map可以进行链式操作,forEach不行
3.map里可以用return,forEach里return不起作用,forEach不能用break,会报错
4.map速度大于forEach
相同点
- 都是循环遍历数组中的每一项
- 执行匿名函数都支持三个参数 item(当前的每一项) index索引 arr原数组
forEach
- 对于基本数据类型,我们当次循环拿到的item,只是forEach给我们在另一个地方复制创建新元素,是和原数组这个元素没有联系的!所以,我们给循环拿到的item赋值都是无用功,不改变原数组!可以采用arr[index]的方法赋予新值,这样就改变了原数组。
// 基础数据类型 原数组不变
let arr=[1,2,3]
let newarr=arr.forEach((item,index)=>{
item=1
})
console.log(arr); //[ 1, 2, 3 ]
console.log(newarr); //undefined
// 基础数据类型 原数组该百年 使用arr[index]
let arr=[1,2,3]
let newarr=arr.forEach((item,index)=>{
// item=1
arr[index]=1
})
console.log(arr); //[ 1, 1, 1 ]
console.log(newarr); //undefined
- 对于引用数据类型,真正的数据是保存在堆内存,栈内只保存了对象的变量以及对应的堆的地址,所以操作Object其实就是直接操作了原数组对象本身,改变原数组
// 引用数据类型 原数组改变
let obj=[{name:'一二',age:3},{name:"布布",age:2}]
let newobj=obj.forEach((item,index,obj)=>{
item.name='一样'
})
console.log(obj); //[ { name: '一样', age: 3 }, { name: '一样', age: 2 } ]原数组该变了
console.log(newobj); //undefined
- 均可以采用arr[index]的方法赋予新值,这样就改变了原数组。
map
- 基本数据类型,原数组不会改变
- 引用数据类型,在map中进行操作时,会改变原数组(与map方法无关)
// 基础数据类型,原数组未改变,返回一个新数组
let marr=[1,2,'xx']
let mnewarr=marr.map((item,index)=>{
item='改变'
return item
})
console.log(marr); //[ 1, 2, 'xx' ]
console.log(mnewarr);//[ '改变', '改变', '改变' ]
// 引用数据类型,原数组改变,返回一个新数组
let mobj=[{name:'四毛'},{name:'八毛'}]
let mnewobj=mobj.map((item,index)=>{
item.name="你好"
return item
})
console.log(mobj); //[ { name: '你好' }, { name: '你好' } ]
console.log(mnewobj);//[ { name: '你好' }, { name: '你好' } ]
基本类型数据和引用类型数据存储的方式不同导致,任何循环方法都可造成此影响