2

Can anyone explain why the obj returns {a:2} instead of {a:1} in this case?

var obj = {a:1};
var data = {b:obj};
data.b.a = 2;

console.log(obj); // {a:2}
13
  • 1
    You did change the property? Commented Jan 19, 2013 at 18:55
  • See related question: stackoverflow.com/questions/728360/… Commented Jan 19, 2013 at 18:56
  • 1
    As in most languages, objects are references in JavaScript... (And this doesn't have anything to do with shallow copying, by the way.) Commented Jan 19, 2013 at 18:56
  • 1
    @minitech If objects are references, names are people. References refer to objects, and objects contain more references, but they're quite separate. Commented Jan 19, 2013 at 18:57
  • 1
    But you didn't create another object, you just created another reference to the same object. If you want to "clone" objects without copying properties, try using the prototype chain. Commented Jan 19, 2013 at 19:11

3 Answers 3

3

objects in javascript are by reference, so when you change one reference you changed them. The meaning of this is you just created a shallow copy, you need to do a deep clone.

Deep copy can be made with jQuery this way:

// Deep copy
var newObject = jQuery.extend(true, {}, obj);

Read this why I used jQuery: What is the most efficient way to deep clone an object in JavaScript?
(It's John Resig here on Stackoverflow...)

Sign up to request clarification or add additional context in comments.

4 Comments

Thank you for your reply. Can you tell me please how can I copy the obj with no conflicts without jquery or other libraries plz?
@artnikpro, it can be done with this: newObj = JSON.decode(JSON.encode(oldObj));, about performance and other problems... read the linked answer.
@artnikpro: Follow the link in the second comment to your question.
Seems like it is not simple to do. I will try to figure it out. Thanks.
0

In this case you're not cloning objects but rather setting additional references to the same variable. data.obj.a and obj.a point to the exact same memory location. Line 3 sets this memory value to 2.

To do a deep clone, try this:

var data = JSON.parse(JSON.stringify(obj));

Comments

0

if using an NS derived browser like FF:

var data = { b: eval ( obj . toSource ( ) ) } ;

or

var data = { b: eval ( uneval ( obj ) ) } ;

if not:

Object . function . deepClone = function(){ 
/*
     highly non-trivial to accommodate objects like:
              animal=123; animal.beastly=432;                                        ie. object "overloading"
              monster = new ( function ( ) { this . this = this } ) ( )            ie. self-referential / recursive
      Note: JSON cannot do these  but  toSource () can handle recursive structures
      alert ( new ( function ( ) { this . this = this } ) ( )  . toSource ( )  );
                                                                                                                   ie.    #1={this:#1#}
      alert ( new ( function ( ) { this [ this ] = this } ) ( )  . toSource ( )  );
                                                                                                                   ie.     #1={'[object Object]':#1#}
      alert ( new ( function ( ) { this [ this . toSource ( )  ] = this } ) ( )  . toSource ( )  );
                                                                                                                   ie.     #1={'({})':#1#}
      alert (    (     #1 = { '({})' : #1# }      )   . toSource ( )  );
                                                                                                                   ie.     #1={'({})':#1#}
*/
 }

var data = { b: obj . deepClone ( )  } ;

There are many, many, many attempts posted in SO to do deepClone as well as
The structured clone algorithm - Web developer guide | MDN

hint: The Emperor has No Clothes

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.