0

I wish to understand the following behaviour when pushing objects into an array.

(1) I create an object, create a property of the object and then push it into an array.

var array = [];
var obj = {};

obj.x = 1;
array.push(obj); 
console.log(array); //Output [{x: 1}]

Consider the two alternatives:

(2a): I change the object's property and so change the object referenced in the array:

obj.x = 2;
console.log(array); //Output [{x: 2}] ... it has been changed

(2b instead of 2a) I make the object reference refer to a new object and create the property, the original object referenced in the array is unchanged:

obj = {}; //Change reference to new object
obj.x = 2;
console.log(array); //Output [{x: 1}] ... it is unchanged

Why is this the case?

P.S: I notice that this distinction is discussed here (Do objects pushed into an array in javascript deep or shallow copy?), but it is not satisfactorily explained.

  • 1
    because it is a reference, not a copy – epascarello Sep 18 '18 at 18:58
  • 1
    Can you please be more specific on what is *unsatisfactory* about the explanation you pointed to? – PM 77-1 Sep 18 '18 at 18:58
  • Didn't you just explain it yourself? 2a modifies the object that is referenced by the variable and array, 2b creates a second object and modifies only that. – Bergi Sep 18 '18 at 19:06
  • The first object is still referenced in the array. This reference was pushed into the array as _obj_. When _obj_ refers to a new object, what is that original reference? – StevenRJClarke1985 Sep 18 '18 at 19:09
  • The original reference still references the original object. An object doesn't need to have any kind of "variable allocating space for it" to exist. If you come from a low-level language: *every* object is just a pointer. The object literal `{}` creates the dynamic object on the heap and returns a reference to it. – Bergi Sep 18 '18 at 20:11

3 Answers3

0

JavaScript objects are pushed onto the array by object reference, that is if you push the object into the array and then later manipulate the object, the array's contents appear to change as well because the array references the same object.

Creating a new object either by initialization or by cloning side-steps this problem, you've got two entirely different objects in the array.

Think of it this way: When you call push on an object the object itself doesn't go into the array, a reference (pointer) to the object does. Primitive types like numbers get copied in, objects don't.

tadman
  • 208,517
  • 23
  • 234
  • 262
0
  1. When you are pushing an object, you adding reference of first object, So thats reason its updated to 2

  2. You are creating new object and assigning to obj and changing that object won't change array value because it is pointing to different reference.

0

I don't know if my poor ASCII diagramming skills would help, but here's an attempt:

-----------------------------------------
(1)
-----------------------------------------

array = []

  [ ]    'array'
   ^--------/

obj = {}

  [ ]    'array'   { }     'obj'
   ^--------/       ^-------/

obj.x = 1

  [ ]    'array'   {x: 1}    'obj'
   ^--------/        ^---------/

array.push(obj)

       ,-----------------v
  [0: * ]    'array'   {x: 1}    'obj'
   ^------------/        ^---------/

-----------------------------------------
(2a)
-----------------------------------------

obj.x = 2

       ,-----------------v
  [0: * ]    'array'   {x: 2}    'obj'
   ^------------/        ^---------/


-----------------------------------------
(2b)
-----------------------------------------

obj = {}

       ,-----------------v
  [0: * ]    'array'   {x: 1}    'obj'    { }
   ^------------/                  `-------^ 


obj.x = 2

       ,-----------------v
  [0: * ]    'array'   {x: 1}    'obj'    {x: 2}
   ^------------/                  `--------^ 
Scott Sauyet
  • 49,207
  • 4
  • 49
  • 103
  • Thank you. I think visually. – StevenRJClarke1985 Sep 18 '18 at 19:21
  • 1
    My confusion stemmed from thinking that there was an _obj_reference in the array, rather than the object being referenced by the 0 index. – StevenRJClarke1985 Sep 18 '18 at 19:22
  • What is the nature of the * you have placed in the array, which points to the object. Is it a type of reference? – StevenRJClarke1985 Sep 18 '18 at 19:27
  • @StevenRJClarke1985: Yes, that's probably the best way to think of it. I simply wanted something in the diagram for the arrow to point from. It looked awkward without it. The point is that the first element of the array (index `0`) points to something else in memory. – Scott Sauyet Sep 18 '18 at 19:35