Using let to declare variables
In the past, I’ve been vocal about why I prefer var
over let
, but I’m starting to come around.
Today, I wanted to look how they differ, and when and why you might want to choose let
over var
.
Variables and scope
Historically in JavaScript, scope was only created within functions.
In the example below, var x = 2
throws an error because x
has already been declared within the current scope.
var x = 1;
if (x === 1) {
// This throws an error:
// Uncaught SyntaxError: Identifier 'x' has already been declared
var x = 2;
}
Similarly, in this example, console.log(i)
will log 10
to the console after our loop runs.
for (var i = 0; i < 10; i++) {
// Loop 10 times
}
console.log(i);
Block scope
By contrast, the let
operator creates block scoped variables.
Block scope is created whenever you have curly braces. That includes functions, like with traditional scope. But it also means things like for
loops and if...else
statements as well.
Looking at our examples again, here, let x = 2
creates a newly defined variable within the scope of the if
statement. Inside the statement, console.log()
logs 2
. Outside of the if
statement, it logs the originally defined 1
, because let x = 2
exists in a different scope.
let x = 1;
if (x === 1) {
// Does NOT throw an error
let x = 2;
// Logs 2
console.log(x);
}
// Logs 1
console.log(x);
Let’s look at our for
loop again. If we use let
to declare i
, its value only exists inside the loop.
Trying to log its value after the loop causes a ReferenceError
, because i
is not defined inside that scope.
for (let i = 0; i < 10; i++) {
// Loop 10 times
}
// Throws an error:
// Uncaught ReferenceError: i is not defined
console.log(i);
What does that mean for you?
My argument for always using var
hinged on two things:
- I don’t want to have to think about which variable declaration operator to use. I’d rather just pick one and run with it.
- The
var
operator has way better browser support. Thelet
operator can’t be polyfilled, and I don’t want to use Babel.
That said, I like the more strict behavior that let
introduces. JavaScript is a very loose language, and anything that forces more structure is, in my opinion, a good thing.
My browser support baseline is also shifting.
For years, I’ve targeted IE9 and above. Today, I think it’s appropriate to consider starting with IE11 for JavaScript that’s non-critical.
Rather than mixing let
and var
, I would use let
for everything in that case.