JavaScript Puzzle - The Too Tidy Assignment
Written by Ian Elliot   
Thursday, 20 June 2019
Article Index
JavaScript Puzzle - The Too Tidy Assignment



The problem was isolated to a leaking of the local variable out into the global context.

You can see this if you try the following program:

var a=100;
var b=200;
var c=300;
alert(a+","+b+","+ c);

function myfunction(){
 var a=b=c=0;
 alert(a+","+b+","+ c);

When the function executes the alert displays 0,0,0 which proves that the variables exist and have been initialized. However the second alert displays 100,0,0 which means that the global variables b and c have been set to zero.

With this information now you should be able to see what is wrong.

JavaScript is a functional language which means that expressions always return a value - even the assignment statement.

So if try:


you will see 10 displayed as this is the result of the assignment.

Now consider the evaluation of

var a=b=c=0;

The first part of the instruction is the var statement which declares the a to be a local variable. Next we have the initialization. When you write:

var a=expression;

the order of events is that a is declared, the expression is evaluated and the value assigned to a. In this case we have to evaluate b=c=0. At this point things go wrong. The b variable isn't declared as local, it is a variable used in an expression without being declared, and so it is identified with the global variable b or a new global variable b is created, the same for c. Finally the 0 is evaluated and stored in c, which provides the result to store in b i.e. zero and finally this is also stored in a.

All three variables end up being set to zero but b and c have been used as global variables.

The reason for the error is to think of var as an operator with a higher precedence than assignment. If this were the case then the var would first be applied to create three local variables and then the assignments would be evaluated. However var is not even an operator, let alone having precedence over assignment, it is a statement and it evaluates the assignment before completing and declaring one variable as local. That is

 var a=b=c=0;

 is equivalent to

var a=expression;

and the expression is b=c=0.


So it is all JavaScript's fault.

The programmer who attempted to make the simplification of the code was right to be annoyed that JavaScript had broken the rule about not doing unexpected things.


 var a=b=c=0;

should be interpreted to mean:

 var a=0: var b=0; var c=0;

OK, if this is the case what about the programmer who wants to write:

var a=b=c+1;

Does this mean

var a=b; var b=c+1;var c+1;

No, clearly this is not about simple syntactic "sugar". 

Even if you throw in some semantics and say that you don't attempt to declare something that is an expression, i.e. the c+1, you still have a potential problem with:

var b=c+1;

unless you interpret it as

var b=expression;

which is what JavaScript actually does!

For example JavaScript does allow;

var b=0, a=b+1

and this creates both b and a as local variables with b set to zero and a set to 1 i.e. it is equivalent to:

var b=0;
var a=b+1;


var a=b+1,b=0;

doesn't work because b isn't defined when a is initialized i.e.:

var a=b+1;

var b=0;

Finally notice that:

var a,b,c=b=a=0;

does work and creates three local variables initialized to zero.

Can you figure out why?
 (answer at the end)


The point is that initialization combined with declaration isn't simple. In compiled languages declaration is a compile time operation and initialization is also usually, but not always, done at compile time. This results in a set of rules for what you can initialize variables to - basically the expression has to have a value at compile time. For example, the simplest thing to do is to restrict initialization to constants - but then the temptation is to extend things to variables with values that can be determined at compile time. This can become very complicated and JavaScript isn't the only language where declaration and initialization are messy.

After you have pointed out what the troublesome expression actually means most JavaScript programmers don't think it's an aberration on the part of JavaScript  - it seems logical.

So how to avoid the problem?

The most obvious way is to understand exactly what every JavaScript statement means in minute detail - obviously not possible.

The alternative is not to try to tidy code to the point where it starts to be a matter of interpretation what the meaning is. In other words if it is a matter of what you expect of an little used construct then don't do it.

Answer to final puzzle:

The reason:

var a,b,c=b=a=0;

works is that a and b are declared as local variables without initialization. Then c is declared as a local variable and set to the result of the expression, which also sets a and b to zero.
That is, the statement is equivalent to:

var a,b;
var c=b=a=0;








More Puzzles

Python Puzzle - Where Did The Time Go?

A Python programming puzzle to get you up to speed. This one is all about time keeping, or is it? There are some strange things that go on in Python when you aren't paying attention. 

Sharpen Your Coding Skills
Vertex Coverings And The Cool Kids Problem

Joe Celko has posed another puzzle that requires you to think like a programmer. This one asks us to find the cool kids in a social network - the ones who taken together know everyone else. This is al [ ... ]

Programmer Puzzle - Python Swallows A Global

Here's a teaser that poses a practical problem - one that crops up in everyday Python programming. See if you can work out the answer before looking at its solution and the pattern to follow to avoid  [ ... ]

Other Articles



Last Updated ( Thursday, 20 June 2019 )