Var, Let, and Const with Hoisting and TDZ

Var, Let, and Const with Hoisting and TDZ

·

5 min read

Introduction to variables

Javascript is a dynamically typed language and hence there is no need to define the datatype of a variable. But we use three keywords to declare a variable in javascript var, let, and const.

var a=6;
let b=6
const c=6;

Accessing the above variables using console.log() method.

console.log(a); //6
console.log(b); //6
console.log(c); //6

Accessing variables without assigning them

Now, let's check what happens if we access those variables without assigning some value

var p;
let q;
const r;
console.log(p); //undefined
console.log(q); //undefined
console.log(r); //SyntaxError: Missing initializer in const declaration

We should declare and initialize the const variable in one single line.

Undefined and Not defined?

Undefined and Not defined are not the same in javaScript.

var p=20;
console.log(p) // undefined
console.log(s); // ReferenceError: s is not defined

Undefined - It is a reserved keyword in javascript. Everything which gets space in the memory will assign to "undefined" until we assign some actual value to it.
Not defined - Accessing variables even before declaring them in the code will give a "not defined" error.

Accessing the variables before declaring

console.log(a); // undefined
console.log(b); //ReferenceError: b is not defined
console.log(c); //ReferenceError: c is not defined
var a=4;
let b=5;
const c=6;

How do "var" and "let" behave differently? How "var a" is giving undefined even when we have not declared the variable before using it? When "var a" is giving undefined, Then how "let and const" are giving us reference error?

Are you also pondering over similar questions? Let's move ahead to solve this mystery.

Accessing variables that are not declared in the code gives an error because of TDZ

What is TDZ or Temporal Dead Zone?

Hoisting - Javascript hoists all the variables, functions, and classes on top of their scope before the code execution starts.

Temporal Dead Zone - It is the area/ block/ zone where the variable is hoisted but not assigned to any value and they are temporarily unavailable in that scope.

A little background story, Every javascript code goes through two phases:-

  1. Memory allocation phase
  2. Code execution phase
var a=6;

Memory creation phase - Every variable and function in the code will get some space in the memory and a special keyword "undefined" is assigned to variables whereas, the functions will store the function body directly in the Memory creation phase.

a = undefined //in memory creation phase

Code execution phase - In the Code execution phase, Code executes line by line. And the variables will get assigned to their respective values (which are defined in the code).

a = 6  //in code execution phase

Now, Let's go back to the same question again:- When all the variables and functions are hoisted then how come "var a" was giving undefined and "let and const" were giving us reference error?

Do variables from let and const really get hoisted?

Yes. Variables declared from all three keywords(var, let, and const) get hoisted and assigned to the undefined keyword. But "let and const" follows a strict principle and gets saved in the script scope. Even though they are assigned to undefined (like var) they are not accessible without assigning a value to them. And that's when they become temporarily unavailable and fall into a dead zone(TDZ). Whereas, "var" variables are hoisted and saved in a global scope. Hence they are accessible even without assigning an actual value to them.

let, const and var.png

If you look at the above image of the console debugger, then you can see that let and const are stored in the script scope. Whereas, var is stored in the global scope.

Var is cool. Isn't it? We can access it anytime, anywhere. But it comes with a lot of disadvantages.

Disadvantages of var declared variables

  • We can redeclare the same variable using var.

    var a=10;
    var a=100;
    

    This is a problem, as we tend to change the essential variables as well. Example- let's take an example of a bank account what if the balance amount variable is declared with var. Then, it can easily be redeclared as 0 even though we have money in our account. It's a little dangerous.

  • We can access var variables without even assigning an actual value to it

    console.log(a) //undefined
    var a=6
    
  • var variables in for loop continue to remain in their state even after the termination of for loop

    for(var i=0; i<3; i++){
      console.log(i); //0 1 2
    }
    console.log("outside",i); // outside 3
    
  • var variables inside the if statement get hoisted to the parent scope which is the global scope. So, even the var variables inside if statement is accessible everywhere. var in if.png

What's next?

Introducing const and let variables

Let variables

  • We cannot redeclare let variables. But always re-assign a value whenever needed.
    let a=4;
    a=5; //valid
    let a=10; //SyntaxError: Identifier 'a' has already been declared
    
  • let variables have a block scope, so they are not accessible outside the block { }
    if(true){
      let a=4;
    }
    console.log(a); //undefined
    
  • As let variables have block scope, they are not even hoisted in the parent scope. They maintain their own block, even while hoisting. let in if.png let inside if.png

Do we need const variables as well?

Yes. At times we don't want the variable, array, or an object to change its property and value. So, we use const because

  • const variables are not allowed to re-assign or re-declare a variable.
    const apple=7;
    apple=4;  //TypeError: Assignment to constant variable.
    
  • const variables are declared and initialized at the same time.
    const papaya=1;
    const apple; //SyntaxError: Missing initializer in const declaration
    
  • Rest of the properties of const declared variable are same as let variables.

Difference between var, let, and const

Reason Var Let const
Accessibility of Variable Functional Scope Block Scope Block Scope
Declaration without initialization Allowed Allowed Not allowed
Declaration and Assignment Can be re-declared and re-assigned within the scope Cannot be re-declared but can be re-assigned within the scope Cannot be re-declared or re-initialized in the scope
Accessed without initialization Yes. Allowed Not Allowed because of TDZ Not allowed because of TDZ

Conclusion

var let const.png

  • Try using const as it is error-prone.
  • Use let if you need to change the value in between the code.
  • Try to avoid var.