Let

The let statement declares a block scope local variable (not function level scope like var).

let count = 2;
console.log(value); // 2
function fun() {
    let count = 4; // different value assigned to count
    console.log(count); // 4
}
fun();
console.log(count); // 2

Redeclaring the same variable within the same function or block scope raises a SyntaxError.

let count = 2;
let count = 3; // Identifier 'count' has already been declared

Hoisting

let will hoist the variable to the top of the block. However, trying to access the variable in the block before the variable declaration results in a ReferenceError.

function fun() {
    console.log(count); // ReferenceError: count is not defined
    let count = 4;
}
fun();

let and const are hoisted (like var and function), but there is a period between entering scope and being declared where they cannot be accessed. This period is the temporal dead zone (TDZ).

var count = 1;
console.log(count); // SyntaxError: Identifier 'count' has already been declared
let count = 4;

Still the above statement throwing error. Because of TDZ

What is temporal dead zone (TDZ) in ES6

In ECMAScript 6, accessing a let or const variable before its declaration (within its scope) causes a ReferenceError.

There are several reasons why const and let have temporal dead zones:

  • To catch programming errors: Being able to access a variable before its declaration is strange. If you do so, it is normally by accident and you should be warned about it.
  • For const: Making const work properly is difficult.
  • Future-proofing for guards: JavaScript may eventually have guards, a mechanism for enforcing at runtime that a variable has the correct value (think runtime type check). If the value of a variable is undefined before its declaration then that value may be in conflict with the guarantee given by its guard.

Constants

const works like let, but the variable you declare must be immediately initialized, with a value that can’t be changed afterwards.

The const declaration creates a read-only reference to a value.

Declaration and Usage

const PI;
console.log(PI); // Missing initializer in const declaration

The value of a constant cannot change through re-assignment, and it can't be redeclared.

const PI = 3.14;
console.log(PI); // 3.14
PI = 3.14;
console.log(PI); // Identifier 'PI' has already been declared    

Cannot re-assign any value to const after declaration.

const PI = 3.14;
PI = 3.14;
console.log(PI); // Uncaught TypeError: Assignment to constant variable.(…)

const Scope

const PI = 3.14;
function fun() {
    const PI = 3.141;
    if(true) {
        const PI = 3.14159;
        console.log(PI); // 3.14159
    }
    console.log(PI); // 3.141
}
console.log(PI); // 3.14
fun();
// Outputs
// 3.14
// 3.14159
// 3.141