记一次数组复制遇到的问题

  我们需要知道的是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=新地址 

你可能感兴趣的:(记一次数组复制遇到的问题)