相信很多人都有用过数组的map方法,都知道map在不影响原数组的情况下,会返回一个新数组。但是当map的数组是非基础类型数据时,是否还能不影响原数组?
- 答案:No,非基础数据类型则会影响到原数组
例子:
- 数组数据是基础类型数据时: [1,2,3]
let c = [1,2,3]
let d = c.map((item)=>{
item = 1
return item
})
// 结果 d = [1,1,1]
此时 对比一下两个数组
c.every((item,indx)=>{
return item === d[indx]
})
得到 false
说明两个数组内容不同,map未修改原数组且返回一个新数组
- 数组数据是非基础类型数据时: [{‘events’:[1,2]},{‘events’:[3,4]}]
let a1 = [{'texts':[1,2]},{'textts':[3,4]}]
// 此处自欺欺人一下,利用concat方法返回一个新数组给c1
let c1 = a1.concat();
c1.map((item,indx)=>{
item.texts = item.texts.map((text,evindx)=>{
text = 6
console.log(texts,'kkk')
return text
})
return item
})
此时你打印c1,a1
你会发现,a1的值也被改了
结果:[{'texts':[6,6]},{'textts':[6,6]}]
此时我们比对两个数组就变得复杂了,推荐Lodash或Underscore比较数组和对象
_.isEqual(array1, array2)
_.isEqual(object1, object2)
//相等则返回true,否则返回false
结论:map如何遍历的数组结构是非基础类型时,会修改到原数组数据
这是由于基础类型是栈内存存name value ,而引用类型的栈内存中的value存放的是其数据的堆内存地址,而其数据则存放在堆内存中,深浅拷贝对基础数组和引用数据类型的理解
我们对于引用类型的赋值若未深拷贝则是会直接修改到原数据,所以,如何处理这个问题呢?
很简单,提前深拷贝需要处理的数组,这样就不会直接修改到原数组
- 题外话:为什么我们上面使用.concat() 还是没有效果呢,其实这和你使用…扩展运算符一样道理,他们都只是深拷贝了数组的第一层数据,再深层的结构是无法深拷贝到的
深拷贝推荐
- lodash等三方的方法,lodash.cloneDeep(objects)
- 循环遍历拷贝:详细可查看深浅拷贝方法