How to deep copy a custom object in JavaScript?

老子叫甜甜 提交于 2019-12-01 03:22:26

Here are 3 different methods for copying objects. Each method has pros and cons, so read through and pick the best for your situation

Object.assign method

Use Object.assign, which "is used to copy the values of all enumerable own properties from one or more source objects to a target object". This copies both values and functions. At the time of writing this, browser support is good but not perfect, but this is the best method IMO of the three.

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

Spread operator method

Alternatively, you can use the spread operator to spread from one object into another. Keep in mind that this will copy the values of keys, but if you the value of a key is a memory address (an other nested object or an array) then it will only be a shallow copy.

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

JSON stringify/parse trick

If the object doesn't have any circular references or functions as values, you can use the json stringify trick:

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

No libraries required, and works very well for most objects.

You can use lodash's cloneDeep function - https://lodash.com/docs/4.16.4#cloneDeep

Example (from docs)

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

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

If you are dealing with a class instance you could use something like this.

You wouldn't need to copy the functions as they are delegated to on the prototype.

// 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>

Lodash _.cloneDeep() method kills the application performance. So I have come up with basic JavaScript solution. I have added it to my GIT repo. My application performance is back to normal after using my solution.

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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!