0

I'm confused as to how object references work in Javascript with regards to arrays and haven't found any relevant material for this specific question. I have the following code. I initialize an array called arr of objects and set a new variable c equal to the first element in the array. If I alter the array element, the variable c is also changed as expected. Therefore I assume c is a pointer to the first element of the array.

However, If I set arr to a new array entirely, the variable c doesn't update. I would expect it to either A) Update to 'chameleon' which is the first element of the new array or, more likely, B) become undefined.

What object is the variable c pointing to after the arr is set equal to a new array? Does it become its own object?

var arr = [{animal: 'cat'}, {animal: 'bear'}];
var c = arr[0];
console.log(JSON.stringify(c.animal));
// Prints 'cat'

arr[0].animal = 'iguana';
console.log(JSON.stringify(c.animal));
// Prints 'iguana'

arr = [{animal: 'chameleon'}, {animal: 'bear'}];
console.log(JSON.stringify(c.animal));
// Prints 'iguana' instead of 'chameleon'
apdm
  • 1,260
  • 1
  • 14
  • 33
  • 2
    [Does Javascript pass by reference?](http://stackoverflow.com/questions/13104494/does-javascript-pass-by-reference) – adeneo Nov 08 '16 at 18:08
  • 1
    why are you stringifying a string? – epascarello Nov 08 '16 at 18:09
  • 2
    c is not a reference to arr[0], its a reference to the object you made on arr[0] – juvian Nov 08 '16 at 18:10
  • Note that you'll see the same effect if you do `arr[0] = {animal: 'dog'}`. – Barmar Nov 08 '16 at 18:10
  • It's the same as it was before you changed what arr referenced. If you pointed at a new array in C the same behavior would occur-it's different data. – Dave Newton Nov 08 '16 at 18:21
  • JavaScript is pass/assign **by value**. `var c = arr[0];` assigns the **value** of `arr[0]` to `c` (the *value* in this case is a *reference* to an object). – Felix Kling Nov 08 '16 at 18:25

5 Answers5

3

c isn't a reference to the first element of arr. It is a reference to an object, and that object just happens to be in arr. No matter what happens to arr, c will continue referring to that object unless you assign a new value to c.

In the second line before the end, you are overwriting the arr variable with a new value. The c value still refers to the same object it did already. Replacing arr with an entirely new value won't change that.

What object is the variable c pointing to after the arr is set equal to a new array? Does it become its own object?

The same object that it was pointing to before you reassigned arr. It hasn't changed.

Another demonstration:

var arr = [{animal: 'cat'}, {animal: 'bear'}];
var c = arr[0];

console.log(c.animal);
// Prints 'cat'

// access the value in arr[0] and modify its `animal` property
arr[0].animal = 'iguana';
console.log(c.animal);
// Prints 'iguana'

// REPLACE the 0th element of arr with a new value
arr[0] = { animal: 'pig' };
console.log(c.animal);
// still prints 'iguana'
JLRishe
  • 99,490
  • 19
  • 131
  • 169
2

It's actually very simple. c doesn't point to arr[0]. c points to the object stored at index [0] inside of arr. That binding stays intact even when arr is reassigned. In other words arr[0] is a means to an end - - to the object stored there. That's what c is referencing, not the instructions on how you got to it.

Now, if you were to run the var c = arr[0]; line again after reassigning arr, c would certainly point to a new object, but you didn't do this. You only assigned c once so it retains its reference to the original object.

Here's a very easy analogy. If I introduce you to my best friend, I have now established a relationship between you and that person (you know him because you went through me). But, If I get into a huge fight with that person (i.e. they are no longer my friend and I no longer have any relationship to them), it doesn't affect your ability to know that person. I simply introduced you two, but the reference is between you and him.

And remember, in JavaScript when you assign an object to a variable (or property), you are assigning a "reference" to that object, not the object itself.

Scott Marcus
  • 64,069
  • 6
  • 49
  • 71
  • The last sentence seems to be a bit vague. It could give the impression to a less informed reader that you mean that JavaScript is *pass by reference* (which is not the case). What value `arr[0]` has is actually irrelevant wrt the relationship between `c` and `arr[0]` in this example. – Felix Kling Nov 08 '16 at 18:29
1

I think the reason for your confusion is that you are thinking in terms of other languages like c, which use pointers that point to specific values in memory. In javascript, array and object variables store references to the actual array/object, the not array/object itself. When a reference is re-assigned, the original array/object is not overwritten, but instead, the reference is changed to point to a different object, also in memory.

For those reasons, in you example, re-assigning to arr will change the reference, pointing to the new array in memory. However, c, which was not re-assigned, will still reference the same object in the original array, which is also still in memory.

Hope that makes sense.

GPicazo
  • 6,516
  • 3
  • 21
  • 24
0

Always be aware how you are passing values around:

http://docstore.mik.ua/orelly/webprog/jscript/ch11_02.htm

Falk
  • 627
  • 5
  • 12
0

You are reassigning the entire array (reference) that arr is pointing to - it is a completely new reference. The variable c points to the same reference as before because you have not changed the reference for c.