Am not new to JS or its syntax, but sometimes, the semantics of the language has me stumped at times. At work today, a colleague mentioned this:
var a = b =
Your colleague is right:
var a = b = [];
a.push('something');
console.log(b); // outputs ["something"]
but:
var a = [], b = [];
a.push('something');
console.log(b); // outputs []
To accomplish this, you need to split the var
declaration from the chained assignment (see:
http://davidshariff.com/blog/chaining-variable-assignments-in-javascript-words-of-caution/ ).
E.g.
var one = 1, two = 2;
one = two = 3; /* Now both equal 3 */
But if you do as you described (var one = two = 3;
in this example) two
leaks into the global space, while one
is declared in the local scope.
With the first example b
is a reference to a
, and b
becomes a global variable, accessible from anywhere (and it replaces any b
variable that may already exist in the global scope).
Yes, they're not the same. var a = b = []
is equivalent to
var a;
b = [];
a = b;
Not only do both a
and b
get assigned the same value (a reference to the same empty array), b
is not declared at all. In strict mode in ECMAScript 5 and later, this will throw a ReferenceError
; otherwise, unless there is already a variable b
in scope, b
is silently created as a property of the global object and acts similarly to a global variable, wherever the code is, even inside a function. Which is not good.
You can see this quite easily:
(function() {
var a = b = [];
})();
console.log(b); // Shows []
Your colleague is right. The first statement creates a new, empty array. Then, a reference to this array is assigned to b. Then, the same reference (which is the result of the assignment expression) is assigned to a. So a and b refer to the same array.
In all other cases, you create two individual arrays.
By the way: This behavior is quite common and is the same in all C based programming languages. So this is not JavaScript specific.
To complement the already provided answers. ref assignments are different from value assignments
var x = y = 3; // by value
y++; // 4
x; // 3
var a = b = []; // by ref
b.push(1); // [1];
a; // [1]
a = [];
a.push(2); // [2];
b; // [1]
Now that we've addressed 2 two, your question also makes reference to linting, which is the practice of "pretty code" (not functional). In fact, JSHint has deprecated all their "pretty code rules"
That been said, I usually use the following style.-
var a, b, c, // first row all unassigned
x = 1, // 1 row per assigned
y = 2,
list = [
'additional',
'indentation'
],
obj = {
A: 'A',
B: 'B'
};
var z = y +2; // created a new `var` cluster since it uses a var from the previous