Is let and const hoisted?

Yes, let and const is hoisted. In javascript all variables declaration are hoisted(var, let and const).

console.log(fruit1);

// undefined

console.log(fruit2);

// ReferenceError

console.log(fruit3);

// ReferenceError

var fruit1 = “apple”;

let fruit2 = “orange”;

const fruit3 = “banana”;

In the example above, when we console log fruit1 why do we get undefined value and not the assigned value “apple”?

And also If let and const are hoisted like var then why do we get reference error ?

When we run javascript file, javascript engine creates a wrapper called Global Execution Context to manage the code. It first goes through the code and stores  in a memory any variable and function that you may have created. This is called hoisting.

Hoisting is often mistaken as a step where variables are moved to the top of the code. This is not accurate. Javascript does not re-arrange the code.

There are two things to remember here.

  • Variable declared with var is initialized with undefined value by javascript.
  • Variable declared with const or let is left uninitialized.

This is the first phase of execution context.

You might wonder why var is set to undefined and let or const is uninitialized?

This is because during the first phase of execution context we don’t know what value is assigned to the variables. Assignment happens in the second phase of execution context.

We only set aside memory space for variables so it can be accessed when codes are executed line by line during the second phase of execution context.

In the second phase of execution context we execute variable declaration. Here we initialized the variable with the assignment value. If no value is assigned to the variables, javascript will set their value to undefined.

let x;

var y;

console.log(x);

// undefined

console.log(y);

//undefined

Remember that const is always declared with value assigned to it otherwise it gives you syntax error.

const z;

Uncaught SyntaxError: Missing initializer in const declaration

const z = “apple”;

(must be initialized when it is declared)

Now let’s revisit our code example again.

console.log(fruit1);

console.log(fruit2);

console.log(fruit3);

var fruit1 = “apple”;

let fruit2 = “orange”;

const fruit3 = “banana”;

Here the javascript engine parses through the codes and stores console.log function (method) and variables in memory.

var fruit1 is set to undefined and let fruit2 and const fruit3 does not get initialized.

According to spec 13.3.1 Let and Const Declarations, let and const should not be accessed until you run through let and const declaration. So in our example above until we execute the code let fruit2 = “orange” and const fruit3 = “banana” , fruit2 and fruit3 are uninitialized and should not be accessed.

In second phase of execution context where we execute the code line by line, we call console.log() function before we execute the variable declaration i.e var fruit1 = “apple”, let fruit2 = “orange” and const fruit3 = “banana”.

Hence, console.log(fruit1) gives undefined (not the assigned value “apple”) and console.log(fruit2) and console.log(fruit3) gives ReferenceError.

Conclusion

Var, let and const gets hoisted but if you access them before variable declaration, var gives undefined and let and const throws ReferenceError.

It is always best to declare them before accessing them in the codes.