我们需要知道的是array属于复杂数据类型,声明复杂数据类型赋值给变量后,变量是一个指向堆内存的地址,也称为引用类型。
因此当我们把一个引用类型如‘数组’,赋值给另一个变量时,实际上是把另一个变量指向了与之相同的地址,当我们改变其中一个时,实际上改变了堆内存中的存储内容,相应的所有指向该地址的数组都发生了变化:
常见的复制数组方法 concat() 和slice()
使用时遇到的问题
//例
let list=[{ name: "lisi", id: 1 }, { name: "wangwu", id: 2 }]
let list1 = list.concat();
list1.map(el => {
if (el.id === 1) {
el.name = 'namename'
}
return el
})
// console.log(list, list1);
image.png
list1是复制的list值,遍历list1并把id等于1的name值改为‘namename’
可以看到跟想象中的不一样,复制的数组和原数组的name值都发生了改变,猜想其实数组本身是一个地址,数组中存在的object1,object2也都有一个地址,当直接用=赋值时。
// 想象中
既list1 === list list1.object1= list.object1 list1.object2= list.object2
/* list1发生改变,list也会发生改变*/
concat方法其实是复制了原数组内object1,object2的地址放到新地址里
// 想象中
既 list1===新地址 list1.object1= list.object1 list1.object2= list.object2
/*
*list1发生改变并不影响原地址 list1.object1中的元素发生改变 list.object1值也会改变。
*list1.object1可以重新指向一个地址 例如 list1.object1={} list1.object1.name="zhangsan"并不会影响到
*原数组。
*/
slice与concat情况一样
找到的解决方法JSON.parse(JSON.stringify(list))
let list=[{ name: "lisi", id: 1 }, { name: "wangwu", id: 2 }]
let list1 = JSON.parse(JSON.stringify(list));
list1.map(el => {
if (el.id === 1) {
el.name = 'namename'
}
return el
})
// console.log(list, list1);
image.png
//想象中
既 list1===新地址 list1.object1= 新地址 list1.object2=新地址
网友评论