开发中深拷贝的问题

一、问题

在使用AntDesignVue的table表格时候,操作列的编辑按钮点击后modal弹出框要使用当前table列的数据,我自然而然的let新数组直接等于当前列record的数据,造成了修改modal里数据时,同时修改了record的原始数据。

二、原因

引用数据类型做直接等号赋值时,两者指针指向同一地址。

三、解决

使用深拷贝,创建一个新的存储地址。

const obj = { ...record }

四、对象与数组的深拷贝

4.1、ES6解构赋值

存在问题:只能拷贝第一层,无法深层拷贝

const originArr = [1, 2, 3, 4]
const originObj = { name: 'Stefan', age: '24' }

const arr = [ ...originArr ]
const obj = { ...originObj }

4.2、JSON转化

存在问题:属性值为function、undefined、symbol的无法转换

const originObj = { name: 'Stefan', age: '24' }
const obj = JSON.parse(JSON.stringify(originObj))

4.3、Object.assign

存在问题:只能拷贝第一层,无法深层拷贝

const originObj = { name: 'Stefan', age: '24' }
const obj = Object.assign({}, originObj)

4.4、循环

存在问题:只能拷贝第一层,无法深层拷贝

const originObj = { name: 'Stefan', age: '24' }
const obj = {}
for (let key in obj) {
  //遍历属性值,深拷贝
  obj[key] = originObj[key]
}

4.5、Slice

存在问题:只能拷贝第一层,无法深层拷贝

const originArr = [1, 2, 3, 4]
const arr = originArr.slice()

4.6、concat

存在问题:只能拷贝第一层,无法深层拷贝

const originArr = [1, 2, 3, 4]
const arr = originArr.concat()

4.7、循环递归

最完善的解决方案,利用递归的方式,可以拷贝到深层对象

function deepClone(source){
  // 判断复制的目标是数组还是对象
  const targetObj = source.constructor === Array ? [] : {};
  for(let keys in source){ // 遍历目标
    if (source.hasOwnProperty(keys)){
      // 如果值是对象,就递归一下;如果是基础数据类型,就直接赋值
      if (source[keys] && typeof source[keys] === 'object') {
        targetObj[keys] = source[keys].constructor === Array ? [] : {}
        targetObj[keys] = deepClone(source[keys])
      } else {
        targetObj[keys] = source[keys]
      }
    } 
  }
  return targetObj
}

五、使用Lodash.js

5.1、安装

yarn add lodash.clonedeep

// npm install lodash.clonedeep

5.2、引入

import clonedeep from 'lodash.clonedeep'

5.3、使用

const res = {
  a: 1,
  b: '',
  c: null,
  d: undefined,
  e: [],
  f: {
    g: 2,
    h: {}
  }
}
const cloneResult = cloneDeep(res)

console.log(cloneResult.a === res.a)
// false

你可能感兴趣的:(javascript)