2

Hope this question is not asked before. In any case I could not find it. I have noticed this variable behavior that only seems to happen with arrays.

The below is how I normally expect variables to behave.

var k = 10,
    m = k;
alert(m); //10
k+=1;
alert(m); //10

And now look how they behave with arrays.

var arr = [],
    arr2 = arr;
alert(arr2); // empty
arr.push(1);
alert(arr2); // 1

It seems with arrays variables are just references to the same array, with numbers they represent two different numbers that have the same value.

I am sorry if this is a noob question, but I have just noticed it. Is it like this with all complex types? And I was wondering the reason behind this behavior. What does the language achieve by doing this?

Mcs
  • 534
  • 1
  • 5
  • 14

5 Answers5

2

In your first code block, you start out with

+-------+   +--------------+
| k: 10 |   | m: undefined |
+-------+   +--------------+

Then this line:

m = k;

copies the value in k into m:

+-------+   +-------+
| k: 10 |   | m: 10 |
+-------+   +-------+

then k+=1 changes the value in k, which has no effect on m:

+-------+   +-------+
| k: 11 |   | m: 10 |
+-------+   +-------+

In second code block, you start out with this:

+------+
| arr  |------+
+------+      |   +-----------+
              +-->| (array )  |
+------+      |   +-----------+
| arr2 |------+   | length: 0 |
+------+          +-----------+

Note that the value in arr and arr2 is just a reference to an array, which exists elsewhere in memory.

So when you push a value, things change to:

+------+
| arr  |------+
+------+      |   +-----------+
              +-->| (array )  |
+------+      |   +-----------+
| arr2 |------+   | length: 0 |
+------+          | 0: 1      |
                  +-----------+

Is it like this with all complex types?

Yes, this is true of all objects (and standard arrays are just objects in JavaScript), as well as the new typed arrays.

The key thing to remember is that variables hold values. When a variable refers to an object or array, the value in the variable is a reference to the object/array, not a copy of it.

Getting it firmly in one's head that object references are values just like (say) numbers is hugely beneficial to understanding JavaScript code (and code in several other languages that work the same way in this regard, like Java).

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
1

Thought I could answer also why it happens:

There are two types of values in javascript:

  1. Complex types
  2. Primitive types

A complex type is what we typically refer to as an object:

[]
{}
new String()
new Date()

Now primitive types are:

'a string'
23
true

So the answer here is that referencing behaves differently on complex types and primitive types.

var aString = 'myString';
var refString = aString;

In this example the value of "aString" is copied over to refString. They are two totally independent values. But referencing a complex type:

var anArray = [];
var refArray = anArray;

var anObject = {};
var refObject = anObject;

In this case it is the exact same array in both variables, also the case for the object.

This also transfers to checking equality:

'my string' === 'my string' // true
23 === 23 // true
true === true // true

Javascript actually just sees that the values look like each other, not that it is the exact same value in memory. Looking at complex types:

{} === {} // false
[] === [] // false

var myObject = {};
var myObjectReferenced = myObject;
myObject === myObjectReferenced // true

This is a very important core concept of JavaScript to understand or you will be in high risk of changing objects you thought was unique, but is actually shared.

Hope this was an okay explanation.

christianalfoni
  • 994
  • 8
  • 12
  • yes it was thanks, equality part is also very important, actually I have today lost a lot of time because of this in my recursive permutation function, which wasn't supposed to share some arrays, but kept sharing them, now it works though. – Mcs Aug 05 '14 at 12:01
0

Both array objects are pointing on the same variables . that is why one will change other will get affected

Ashisha Nautiyal
  • 1,389
  • 2
  • 19
  • 39
0

Numbers are primitives in javascript. This means the actual data is stored directly on the variables itself.

var k = 10,
    m = k;

in the first case m and k receive two different copies of 10.The assignment operation copies the value and any changes on m does not impact the other and vice versa(simply because they are two different copies).

Quite reversely Arrays are reference types in javascript

var arr = [],
    arr2 = arr;

The assignment operation copies the address,so any modifications to the object through one variable would impact the other.

Prabhu Murthy
  • 9,031
  • 5
  • 29
  • 36
0

There are two kind of variable in JavaScript (and in other languages as well). The fist kind is reserved for what is called "primitive" types, mainly numbers, string and booleans. The second type is for "reference" types which is all other types of objects.

You can think about it this way: for primitive types each value is stored in its own drawer. For example drawer x has the value of 1, drawer y has the value of "John", etc. So when you access drawer x you are accessing the value inside directly.

In the case of reference types, instead of storing the value of the variable in the drawer itself, you only store the directions of how retrieve this value from its own memory location hidden somewhere in the back. So when you copy the contents of a "reference drawer" to another variable you are not copying the value but only the directions, so now you have two drawers that have directions to access the same value.

Why this is done this way is rather complex, but basically it has to do with managing the memory of your program as efficient as possible.

Julio Garcia
  • 1,904
  • 16
  • 26