Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does variable assignment work in JavaScript?

Tags:

javascript

So I was playing around the other day just to see exactly how mass assignment works in JavaScript.

First I tried this example in the console:

a = b = {}; a.foo = 'bar'; console.log(b.foo); 

The result was "bar" being displayed in an alert. That is fair enough, a and b are really just aliases to the same object. Then I thought, how could I make this example simpler.

a = b = 'foo'; a = 'bar'; console.log(b); 

That is pretty much the same thing, isn't it? Well this time, it returns foo not bar as I would expect from the behaviour of the first example.

Why does this happen?

N.B. This example could be simplified even more with the following code:

a = {};  b = a;  a.foo = 'bar';  console.log(b.foo);    a = 'foo';  b = a;  a = 'bar';  console.log(b);

(I suspect that JavaScript treats primitives such as strings and integers differently to hashes. Hashes return a pointer while "core" primitives return a copy of themselves)

like image 315
Chris Lloyd Avatar asked Feb 04 '09 00:02

Chris Lloyd


People also ask

How JavaScript variables are assigned?

Variables in JavaScript are used to store data that will be used in our program. A variable can point to almost any type of value including numbers, strings, arrays, objects, and functions. Variables are assigned values using the = operator.

How does assignment work in JavaScript?

The simple assignment operator ( = ) is used to assign a value to a variable. The assignment operation evaluates to the assigned value. Chaining the assignment operator is possible in order to assign a single value to multiple variables.

What happens when you assign a variable?

The act of assignment to a variable allocates the name and space for the variable to contain a value. We saw that we can assign a variable a numeric value as well as a string (text) value.


2 Answers

In the first example, you are setting a property of an existing object. In the second example, you are assigning a brand new object.

a = b = {}; 

a and b are now pointers to the same object. So when you do:

a.foo = 'bar'; 

It sets b.foo as well since a and b point to the same object.

However!

If you do this instead:

a = 'bar'; 

you are saying that a points to a different object now. This has no effect on what a pointed to before.

In JavaScript, assigning a variable and assigning a property are 2 different operations. It's best to think of variables as pointers to objects, and when you assign directly to a variable, you are not modifying any objects, merely repointing your variable to a different object.

But assigning a property, like a.foo, will modify the object that a points to. This, of course, also modifies all other references that point to this object simply because they all point to the same object.

like image 141
Alex Wayne Avatar answered Sep 20 '22 20:09

Alex Wayne


Your question has already been satisfyingly answered by Squeegy - it has nothing to do with objects vs. primitives, but with reassignment of variables vs. setting properties in the same referenced object.

There seems to be a lot of confusion about JavaScript types in the answers and comments, so here's a small introduction to JavaScript's type system:

In JavaScript, there are two fundamentally different kinds of values: primitives and objects (and there is no thing like a 'hash').

Strings, numbers and booleans as well as null and undefined are primitives, objects are everything which can have properties. Even arrays and functions are regular objects and therefore can hold arbitrary properties. They just differ in the internal [[Class]] property (functions additionally have a property called [[Call]] and [[Construct]], but hey, that's details).

The reason that primitive values may behave like objects is because of autoboxing, but the primitives themselves can't hold any properties.

Here is an example:

var a = 'quux'; a.foo = 'bar'; document.writeln(a.foo); 

This will output undefined: a holds a primitive value, which gets promoted to an object when assigning the property foo. But this new object is immediately discarded, so the value of foo is lost.

Think of it like this:

var a = 'quux'; new String(a).foo = 'bar'; // we never save this new object anywhere! document.writeln(new String(a).foo); // a completly new object gets created 
like image 26
Christoph Avatar answered Sep 24 '22 20:09

Christoph