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.

Article Link:

/en/archive/es6-variables/

# Related Articles