Javascript declarations and assignments

This week I was chasing a javascript bug, which ended up in the following lines:

1
2
3
4
5
6
7
8
9
10
11
12
13
...
renderer: function(layer, text){
var tag = node = Ext.apply({
color: '#FCFCFC',
background: '#666666'
}, layer);
tag.text = tag.text text;
if(node.disabled){
tag.style = "color: #CCC !important";
}
return tag;
},
...

Can you spot the issue?

This line mixes declarations and assignments:

1
var tag = node = Ext.apply({...})

The author thought they were initializing two local vars tag and node. Unfortunately, Javascript is a bit surprising here.

Take the following example:

1
2
3
4
5
6
function test(){
var a = b = 2;
alert(a, b);
}
test();
alert(b);
  • Javascript starts by evaluating b = 2. This is an assignment of the value 2 to the variable b.
  • Because b does not exist, Javascript will actually create a brand new global variable b, and attach it to the current context, in this case window. This is usually something you don’t want to do, and it made bug finding much trickier.
  • The rest of the expression hides the problem. The assignment returns the value that was just assigned, so the expression var a = b = 2 now becomes var a = 2. This correctly creates a local variable a containing the value 2, hiding the damage it has created with b in the global scope.

Note that strict mode fixes this and throws a ReferenceError exception.

dark
sans