ECMAScript 2015 (ES6) provides a stricter way to declare variables: let which can be used to supersede legacy var statement. The let statement declares a block scope local variable while the variables declared with var are scoped to the function block level. Although it is very loose and comfortable to declare variables with var, but this characteristic usually leads to some unexpected behaviors, especially in a complicated project.
Block scope
When I needed to declare variables inside if-statements, it was always difficult to choose between declaring the variables on the top of function context and declaring the variables inside if-statements. With let statement, now I feel free to declare variables inside if-statements like the way I do in c#.
function foo() {
if (true) {
var a = 4; // a is scoped to the foo function
let b = 5; // b is scoped to the if-statement
console.log(a); // 4
console.log(b); // 5
}
}
console.log(a); // 4
console.log(b); // ReferenceError
Let's take a look at the following code, have you been confused why the alert numbers are always same when you click different buttons?
var buttonList = document.getElementsByTagName('button');
for (var i = 0; i < buttonList.length; i++) {
buttonList[i].onclick = function() {
alert(i);
}
}
Now we can simply solve this problem by using let to declare the variable "i" as it is now scoped to each for-statement only.
var buttonList = document.getElementsByTagName('button');
for (let i = 0; i < buttonList.length; i++) {
buttonList[i].onclick = function() {
alert(i);
}
}
Declaring before referencing
In ECMAScript 6, let does not hoist the variable to the top of the block. If you reference a variable in a block before the let declaration for that variable is encountered, this results in a ReferenceError, because the variable is in a "temporal dead zone" from the start of the block until the declaration is processed.
if (true) {
console.log(a); // ReferenceError
let a = 3;
}
No redeclaration
Redeclaration of the same variable in the same block scope results in a TypeError
if (true) {
let a = 1;
let a = 2; // TypeError
}
Availability
- Chrome 41.0 +
- Firefox 39 +
- Internet Explorer 11
- io.js 3.0.0 +
- Microsoft Edge
- Node.js 0.11 + (With Harmony flag on)