0

I'm having problems with references when I try to copy/clone an object into a variable and then, change values of one and don't affect the another one.

I've been having a look into the doc of Object.Assign method, and I tried what the have for deep clone unsuccessfully.

I created a plnkr in order to express myself better and in case you know how to do it properly.

Code Sample in here

const value = 20.20;
let a = { a: 10 };
let bb = { v: value };
let b = { b: 20, bb: bb };
let c = { c: 30 };
let object1 = { name: 'cloneObject', a, b, c }
let object2 = Object.assign({}, object1);
let object3 = Object.assign({}, object1);

object1.name = 'it works fine';
object1.b.bb.v = 999; // this will change same property in object2 & object3 and it shouldn't

document.getElementById('expected1').innerHTML = object1.b.bb.v;
document.getElementById('expected2').innerHTML = value;
document.getElementById('expected3').innerHTML = value;


document.getElementById('name1').innerHTML = object1.name;
document.getElementById('name2').innerHTML = object2.name;
document.getElementById('name3').innerHTML = object3.name;

document.getElementById('value1').innerHTML = object1.b.bb.v;
document.getElementById('value2').innerHTML = object2.b.bb.v;
document.getElementById('value3').innerHTML = object3.b.bb.v;
<table style="width:100%; text-align: center">
  <tr>
    
    <th>Object</th>
    
    <th>Name</th>
    
    <th>Value</th>
    
    <th>Expected Value</th>
  </tr>
  <tr>
    <td>Object 1</td>
    <td id='name1'></td>
    <td id='value1'></td>
    <td id='expected1'></td>
  </tr>
  <tr>
    <td>Object 2</td>
    <td id='name2'></td>
    <td id='value2'></td>
    <td id='expected2'></td>
  </tr>
  <tr>
    <td>Object 3</td>
    <td id='name3'></td>
    <td id='value3'></td>
    <td id='expected3'></td>
  </tr>
</table>

With @czosel answer, I got:

JSON.parse(JSON.stringify(object1));

So it would looks like this:

  let object1 = {name: 'cloneObject', a, b, c}
  let object2 = JSON.parse(JSON.stringify(object1));
  let object3 = JSON.parse(JSON.stringify(object1));

I find @gon250 answer better, as I'm going to implement it in the parent class and it will inheritance the method by default. I think recursiveness will be more efficient.

Thanks! :)

Alejandro Lora
  • 7,203
  • 3
  • 18
  • 34

2 Answers2

1

Object.assign doesn't do deep cloning, see Warning for Deep Clone (MDN).

For alternatives, please see this popular question.

Community
  • 1
  • 1
Christian Zosel
  • 1,424
  • 1
  • 9
  • 16
1

Below you can see a simple function to clone an object:

function cloneObject(myObj) {
    var temp = myObj.constructor();
    if (myObj === null || typeof myObj !== 'object') {
        return myObj;
    }
    for (var key in myObj) {
        temp[key] = cloneObject(myObj[key]);
    }
    return temp;
}

here is an example implementing the function into your code:

https://jsfiddle.net/gon250/4qx247th/

gon250
  • 3,405
  • 6
  • 44
  • 75