0

Take the following code

var a = b = [];
a.push('value');
if (a === b) {
    console.log('a === b'); // this will execute
}

console.log(a, b); // ["value"] ["value"]

What gives? Why are both a and b modified? Is the var declaration making b a live copy of a? If so, then how come the same cannot apply for regular variable assignment such as:

var a = b = '';
a = 'value';
if (a === b) {
    console.log('a === b'); // this will never run
}

console.log(a, b); // value

Of course, using the following declaration solves the problem in the initial example:

var a = [], b = [];

But the behavior in the initial example struck me as odd, especially that it only applies to array operations.

If it helps, I'm using Google Chrome 10.0.648.82 beta

3 Answers 3

6

The concept you need to grok is referencing. When you assign a variable to another one which points to an object ( [], new Array, {}, new Object, functions, and so forth ) in ECMAScript, the reference is passed. b will refer to a unless you create a new object and assign it to b.

To reiterate, var a = [], b = [] creates two distinct arrays. var a = b = [] assigns b to [] and then b to a which picks up the same exact object stored in memory. Any mutator methods will mutate that object and any variables assigned to that object will refer to that object.

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

1 Comment

"assigns b to [] and then a to b" should be "assigns [] to b and then b to a".
4

When you store "an object" (including an array) in a variable, what you're really storing is a reference (or "pointer") to the object, not a copy of the object itself. That is, the object exists somewhere in memory, and what's stored in the variable is a piece of information that tells the interpreter where to find that object.

In contrast, primitives like numbers or booleans are actually stored in the variable.

So in my best ASCII art, when you have the code

var y = [];

...you end up with this:

+−−−−−−−−−−+            
|     y    |            
+−−−−−−−−−−+            +−−−−−−−−−−−−−−−−−−+
| Ref55467 |−−−−−−−−−−−>| The actual array |
+−−−−−−−−−−+            +−−−−−−−−−−−−−−−−−−+
                        | []               |
                        +−−−−−−−−−−−−−−−−−−+

(Obviously, the Ref55467 is just an example, and you can never actually see the object reference's underlying value in code.)

...whereas with:

var x = 32;

...you end up with:

+−−−−−−−−−−+
|     x    |
+−−−−−−−−−−+
|       32 |
+−−−−−−−−−−+

Now let's look at your

var a = b = [];

That looks like this:

+−−−−−−−−−−+
|     a    |
+−−−−−−−−−−+
| Ref55467 |−−−−−−+     
+−−−−−−−−−−+      |     
                  |     +−−−−−−−−−−−−−−−−−−+
                  +−−−−>| The actual array |
                  |     +−−−−−−−−−−−−−−−−−−+
+−−−−−−−−−−+      |     | []               |
|     b    |      |     +−−−−−−−−−−−−−−−−−−+
+−−−−−−−−−−+      |
| Ref55467 |−−−−−−+
+−−−−−−−−−−+

Both a and b reference (point to) the same array in memory, and so operations that change the array, change the array, regardless of which reference you invoke them on.

In contrast with:

var a = b = 32;

....which looks like:

+−−−−−−−−−−+
|     a    |
+−−−−−−−−−−+
|       32 |
+−−−−−−−−−−+

+−−−−−−−−−−+
|     b    |
+−−−−−−−−−−+
|       32 |
+−−−−−−−−−−+

The number 32 is actually stored in each place, rather than being in a central place both variables point to.

This is also true when you pass values into functions. With an object reference, the value you're passing into the function is an object reference. You're not actually passing the object into the function, just a reference to it. And that means if the function uses the reference to operate on the object, you see the result in the calling code. Example:

function foo(theArray) {
    theArray[0] = 1;
}

var a = ["one", "two", "three"];
foo(a);
alert(a[0]); // alerts "1"

When we called foo, we passed in a reference to the array object, and so when foo used that to modify the array, we see the result.

Comments

2

It's not a live copy, it's an object referencing to the same instance.

When you run [] you're doing new Array(), so, you're assigning the new Array instance to a and b.

Good luck!

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.