ES6 Variables - let and const
ES6 has been officially released for a month now. I’ll be sharing some study notes and my understanding of it.
New Keywords: let and const
JavaScript has always used var to declare variables.
function foo(){
var a = 1;
console.log(a)
}
foo(); //1
Now we have two new friends: let and const.
The let Command
function foo(){
let a = 1;
console.log(a)
}
foo(); //1
This looks the same as var. Let’s look at the next example.
if(true){
var a =1;
}
console.log(a) // 1
if(true){
let a =1;
}
console.log(a) // Error: a is not defined
In a for loop:
for (var i = 0; i < 10; i++) {
}
console.log(i) // 10
for (let i = 0; i < 10; i++) {
}
console.log(i) // Error: i is not defined
The examples above show that let is only effective within block scope, while var acts as a global variable in these cases.
Let’s look at another example:
var arr = [];
for (var i = 0; i < 3; i++) {
arr.push(function(){
return i;
})
}
console.log(arr[0]()) //3
console.log(arr[1]()) //3
console.log(arr[2]()) //3
Every function in the array outputs 3 when called.
This is probably not what we expected.
Here, var i is a global variable. Each time i++ runs, it overwrites the previous value.
So when the functions in arr run, they all return the global variable i.
var arr = [];
for (let i = 0; i < 3; i++) {
arr.push(function(){
return i;
})
}
console.log(arr[0]()) //0
console.log(arr[1]()) //1
console.log(arr[2]()) //2
Here, let i is a local variable. Each function in arr returns its own local i, which is a new variable each iteration.
So each function outputs its corresponding value.
How can we achieve the same effect with var?
var arr = [];
for (var i = 0; i < 3; i++) {
(function(i){
arr.push(function(){
return i
})
})(i)
}
console.log(arr[0]()) //0
console.log(arr[1]()) //1
console.log(arr[2]()) //2
We add an IIFE inside the for loop, passing i into it. Each iteration effectively redeclares i inside the IIFE, so the i inside is not affected by the outer global i.
Variable Hoisting
console.log(foo) // undefined
var foo =1;
Variables declared with var are hoisted. Accessing them before assignment returns undefined without throwing an error.
console.log(foo) // Error
let foo =1;
Using let, it throws an error. let does not support hoisting. You must declare it before using it.
Temporal Dead Zone (TDZ)
Because let variables must be declared before use, the concept of a “temporal dead zone” was introduced.
What is a temporal dead zone?
{
// Temporal dead zone starts
console.log(foo) // Error
// Temporal dead zone ends after foo is declared
let foo =1;
console.log(foo);
}
In a block scope, the area from the beginning of scope execution to the point where the variable is declared is called the temporal dead zone.
Using a variable in the temporal dead zone is not allowed.
No Redeclaration
var foo = 1;
var foo = 2
console.log(foo) //2
let foo = 1;
let foo = 2; // Error
console.log(foo);
Variables declared with let cannot be redeclared.
The const Command
The const keyword declares constants.
What is a constant? A variable declared with const is read-only and cannot be modified.
var foo=1;
foo =2; //2
const FOO=1;
FOO =2; // Error: "FOO" is read-only
Generally, constants are named using all uppercase letters.
const also shares the same features as let: no hoisting, temporal dead zone, no redeclaration, and can only be used within its block scope.