0

I am new to ReactJS and I found a curious thing about Object.assign():

const B = {
    k1: 'b',
    k2: 'bb',
    treedata: [{
        children: ['g']
    }]
}

var A = Object.assign({}, B);
A.treedata[0].children = [1];
console.log(B)

As you can see, after Object.assign(), changing object A will also change object B. Why does this happen and how can you avoid this?

Tom
  • 1,636
  • 2
  • 13
  • 21
charles chen
  • 82
  • 1
  • 9
  • 1
    Nothing to do with ReactJS, this is how JavaScript works (and Ruby, and Python...). – Amadan Aug 01 '18 at 07:14
  • I see, I am doing a react practice, sorry for the tag. – charles chen Aug 01 '18 at 07:16
  • 1
    `Object.assign` only copies properties into a new object. If a property is a reference to another object, like in your case `treedata` is, then `Object.assign` copies a reference, thus objects A and B point to the same `treedata`. – Anton Harniakou Aug 01 '18 at 07:17
  • you can read here also to be clear about Object.assign() https://osmangoni.info/posts/when-object-assign-is-risky/ – Osman Goni Nahid Aug 01 '18 at 07:18
  • The explanation and answer to this issue is mentioned here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign - under the title "warning for deep clone" – ilibilibom Jun 02 '20 at 07:45

1 Answers1

6

You need to parse and strigify object and then use object.assign, like this var A = Object.assign({}, JSON.parse(JSON.stringify(B)));, so that the original object dont change

Check out the snippet

const B = {
k1 : 'b', 
k2 : 'bb', 
treedata : [{ title: 'title', key: -1, fieldName: '', from: -1, to: -1, children: ['g'] }]
}

var A = Object.assign({}, JSON.parse(JSON.stringify(B))); 

A.treedata[0].children = [1];
alert(B.treedata[0].children);
Akhil Aravind
  • 5,741
  • 16
  • 35
  • thanks Aravind! that helps a lot. – charles chen Aug 01 '18 at 07:15
  • @charleschen ready to help anytime – Akhil Aravind Aug 01 '18 at 07:16
  • 1
    "need to parse and stringify" - no, you just need to deep copy. "parse and stringify" is one way to do that (and not the best one, given its limitations). Please refer instead to [this thread](https://stackoverflow.com/questions/122102/what-is-the-most-efficient-way-to-deep-clone-an-object-in-javascript). – Amadan Aug 01 '18 at 07:16
  • @Amadan can you describe deep copy? I really want to know the simple solution. – charles chen Aug 01 '18 at 07:18
  • There is no simple solution, since there is no native deep copy in JavaScript. The problems with JSON route is it ican't copy circular structures, and can't copy anything that isn't a JSON primitive. I already linked the canonical Stack Overflow thread that deals with deep copy in JavaScript. (Also see [Wikipedia on Object copying](https://en.wikipedia.org/wiki/Object_copying) to understand the problem.) – Amadan Aug 01 '18 at 07:20
  • @Amadan Ok, I have seen the link just now, thanks again! – charles chen Aug 01 '18 at 07:23