【 JS 】深拷贝和浅拷贝——主打便捷查阅

91 阅读2分钟

在JS中有多种方式复制对象,其中讨论最多的是深拷贝和浅拷贝~

先通过一个具体的例子来说明拷贝的应用场景

let originalObject = {
  name: 'John',
  age: 30,
  address: {
    city: 'New York',
    country: 'USA'
  }
};

如上如果我们只关心 originalObject 的基本结构,而不关心 address 对象内部的引用关系,那么就可以使用浅拷贝。 这是因为浅拷贝会创建一个新对象,其中包含了 originalObject 的属性,但不会创建 address 对象的新引用。 故此时修改新对象中的 address 属性将会影响原始对象。

通过这个例子可以推导出:

如果目标对象只包含一层属性,浅拷贝其实也是深拷贝,随便用~

如果目标对象包含多层时,需要更深层次的复制时,那么就需要使用深拷贝~


下面依次归纳深浅拷贝实现方式👊

深拷贝

1、JSON.parse(JSON.stringify(temp))

可以实现数组或对象深拷贝,但不能处理函数和正则(我觉得日常属它最好用)

let temp = [{  name: '37' }];
let arr = JSON.parse(JSON.stringify(temp));

2、lodash的_.cloneDeep

const _ = require('lodash');

const originalObject = {
  key1: 'value1',
  key2: {
    key3: 'value3',
    key4: [1, 2, 3]
  }
};

const clonedObject = _.cloneDeep(originalObject);

3、手写递归

function getDataType(value) {
  return Object.prototype.toString.call(value).slice(8, -1)
}

function deepClone(value) {
  const dataType = getDataType(value)
  let result
  if (dataType === 'Object') {
    result = {}
  } else if (dataType === 'Array') {
    result = []
  } else {
    return value
  }
  for (let i in value) {
    if (getDataType(value[i]) === 'Array' || getDataType(value[i]) === 'Object') {
      result[i] = deepClone(value[i])
    } else {
      result[i] = value[i]
    }
  }
  return result
}

浅拷贝

1、Object.assign()

let obj1 = { person: { name: "37" }, sports:'basketball' }; 
let obj2 = Object.assign({}, obj1);

2、lodash的_.clone

const _ = require('lodash');

const originalObject = {
  key1: 'value1',
  key2: {
    key3: 'value3',
    key4: [1, 2, 3]
  }
};

const clonedObject = _.clone(originalObject);

3、展开运算符...

let obj1 = { person: { name: "37" }, sports:'basketball' }; 
let obj2 = {...obj1}

let obj3 = [1, person: { name: "37" }]
let obj4 = [...obj3]