如何在JavaScript中深层复制自定义对象?

问题描述 投票:9回答:4

我一直在这里冲浪一段时间,仍然没有找到适合我的答案。

有没有办法在JS中深层复制非普通对象?

我已经尝试了jQuery.extend(true, {}, this),但它只克隆了一些,剩下的仍然是另一个对象的参考。

javascript clone
4个回答
11
投票

以下是3种不同的复制对象的方法。每种方法都有利有弊,所以请仔细阅读并选择最适合您情况的方法

Object.assign method

使用Object.assign,“用于将所有可枚举的自有属性的值从一个或多个源对象复制到目标对象”。这会复制值和函数。在撰写本文时,浏览器支持很好,但并不完美,但这是三者中最好的IMO方法。

const obj1 = {a:1, b:2};
const obj1Copy = Object.assign(obj1)

Spread operator method

或者,您可以使用spread operator从一个对象传播到另一个对象。请记住,这将复制键的值,但如果键的值是内存地址(另一个嵌套对象或数组),那么它只是一个浅拷贝。

const obj1 = {a: () => {}, b:2}
const obj1Copy = { ...obj1 }

JSON stringify/parse trick

如果对象没有任何循环引用或函数作为值,则可以使用json stringify技巧:

let myCopy = JSON.parse(JSON.stringify(myObject));

不需要库,并且对大多数对象都很有效。


4
投票

你可以使用lodash的cloneDeep函数 - https://lodash.com/docs/4.16.4#cloneDeep

示例(来自docs)

var objects = [{ 'a': 1 }, { 'b': 2 }];

var deep = _.cloneDeep(objects);
console.log(deep[0] === objects[0]);
// => false

0
投票

如果你正在处理一个类实例,你可以使用这样的东西。

您不需要复制原型上委派给它们的函数。

// myObject constructor
function myObject(foo, bar){
  this.foo = foo
  this.bar = bar
}
// delegate the functions to a prototype
myObject.prototype.something = function(){
  console.log('something')
}

function instanceCopy(obj) {
  // copy the object by the constructor
  const copy = new obj.constructor()
  const keys = Object.keys(obj)
  keys.forEach(key => {
    copy[key] = obj[key]
  })
  return copy
}

const myObj = new myObject('foo', 'bar')
const copyObj = instanceCopy(myObj)

console.log('myObj', myObj)
console.log('copyObj', copyObj)
console.log('same ?', copyObj === myObj)

// can we still call the functions
copyObj.something()
<script src="https://codepen.io/synthet1c/pen/WrQapG.js"></script>

-1
投票

Lodash _.cloneDeep()方法会杀死应用程序性能。所以我提出了基本的JavaScript解决方案。我已将它添加到我的GIT仓库中。使用我的解决方案后,我的应用程序性能恢复正常。

https://github.com/manideeppabba1991/javascript_util_functions/blob/master/clone_Array_or_Object.js

© www.soinside.com 2019 - 2024. All rights reserved.