FundamentalsChapter 10 of 21
var
The old declaration, why it behaves oddly, and why you will still meet it.
You will not write var, but you will read it. Every JavaScript file older than about 2016 uses it, so it is worth twenty minutes to recognise what it does.
Function scope, not block scope
let and const live inside the nearest braces. var ignores blocks entirely and lives in the whole function.
JavaScript
function check() {
if (true) {
var inside = 'leaked';
}
return inside;
}
console.log(check());Output
leaked
The same code with let throws a ReferenceError, which is the more useful answer.
Hoisting
A var declaration is moved to the top of its function before anything runs. The assignment stays where it was, so the name exists early holding undefined.
JavaScript
function show() {
console.log(value);
var value = 'set later';
console.log(value);
}
show();Output
undefined set later
No error, just undefined, which is exactly the kind of bug that survives to production. let makes the same code throw.
The classic loop bug
Because there is one var for the whole function rather than one per pass, everything that captures it ends up sharing the final value.
JavaScript
var jobs = [];
for (var i = 0; i < 3; i++) {
jobs.push(function () { return i; });
}
console.log(jobs.map(function (job) { return job(); }));Output
[3, 3, 3]
All three functions read the same i, and by the time they run the loop has finished and left it at 3. Change var to let and the answer becomes [0, 1, 2].
Redeclaration is allowed
Declaring the same var twice is legal and silent, so two unrelated pieces of code can share a name by accident.
JavaScript
var total = 1;
var total = 2;
console.log(total);Output
2
Note
Recognise it, do not reach for it. There is no case where var is the better choice in new code.
Test yourself
2 questionsWhat does hoisting do to a var declaration?
Show the answer
Moves the declaration to the top of the function, leaving the assignment in place Which is why the name exists early holding undefined instead of throwing.
Why does a var loop counter give [3, 3, 3]?
Show the answer
There is one counter for the whole function, shared by every function made in the loop let creates a fresh binding each pass, which is the whole point of the change.
Operators
The symbols that combine values, and the order they apply in.