DEV Community

Rajesh T
Rajesh T

Posted on

JavaScript compiler , Scope & TDZ in depth

JavaScript is a compiled & interpreted language

Most of the beginners can confuse about this statement. When we are coming from C, C++ background, where the those compilers can compile our code into low level, the JavaScript compiler is different than that.

To understand the role of compiler in JavaScript,We should know about roles of JavaScript Engine.

Alt text of image

Now let us understand the role of compiler with an example.

var data=100;

It is variable declaration and initialization.Even though it is appearing as single statement,Actually,
" It is combination of two different actions which can occur at two different situations "

Action-1:

  • when compiler encountering "var a", then ,it asks scope,to see a variable "a" already existed for that particular scope collection .
  • If it is already there,the compiler ignores the declaration and moves on.
    In this example, the variable is global and not already existed, so the compiler asks Scope to declare a variable in its Scope collection

  • Compiler then produces code for Engine to later execute, to handle the a = 2 assignment. That means assignment(data=100) will be done during execution

So, the scope of a variable is decided during compilation time and assignment will be done during execution time

var data=100; return data;

The same thing will be happened to a function also. That means the function declaration will be done at a specific scope during compilation and assignment of function definition will be done during execution.

var testFunction=function(){ return "testFunction called"; } testFunction();

Note: The JS engine compiles your code sometimes during execution,especially when dealing with function execution

With this knowledge,let us try the following example.

return a; var a=100;

Here, actually, we expected an error, because we returned the value of variable "a" before it is even declared. But surprisingly, it returned "undefined" which is default value of a variable.This is because, the scope of variable a is declared during compilation and also initialized with "undefined". That why,it has returned "undefined" instead of error. That means, the variable declaration is " Hoisted ".

Now let us observe the following

return a;

It has generated "Reference Error" ,because RHS lookup failure.It means,it search for the value of a variable which is not yet declared. So, that variable declaration is not available at its Scope .

The same thing would be happened with functions too.

//calling function before declaration //but the declaration will be hoisted testFunction(); function testFunction(){ console.log("test function called"); }

But when we assign a function to a variable, the that variable will be hoisted and generates Type error

//calling function before declaration //but the declaration will be hoisted testFunction(); var testFunction=function (){ console.log("test function called"); }

Temporal Dead Zone

Here is the MDN’s explanation of the temporal dead zone:
In ECMAScript 2015, let bindings are not subject to Variable Hoisting, which means that let declarations do not move to the top of the current execution context. Referencing the variable in the block before the initialization results in a ReferenceError (contrary to a variable declared with var, which will just have the undefined value). The variable is in a “temporal dead zone” from the start of the block until the initialization is processed

To understand this lengthy statement, first we should know the difference between the old one ,called "var" and the "let" which was introduced in ES6.

Variables declared by "var" has Function scope and those declared with "let" has Block scope

var marks=90; var testFunction=function(){ if(marks>80){ let status="First grade" return status; } } testFunction();

Here the variable "marks" is in global scope which can be known to all functions of that file. But the variable "status" has Block scope and known only to if block . When we tried to access "status" from outside of if block, it generates Refference error

var marks=90; var testFunction=function(){ if(marks>80){ let status="First grade" } return status; } testFunction();

Now, let us see about TDZ of "let". Once we revisit the the definition of TDZ,"let bindings are not subject to Variable Hoisting". That means like "var", the variables declared with "let" will not be hoisted. That means no initialization will be done automatically like "var" with "undefined".

let a=100; return a;

But, because of TDZ, the variables declared with "let" will not be initialized. Because of this fact, when we try to access then before their initialization we will get Reference error

return a; let a=100;

Hope this brief discussion helped you to understand the basics in clear way.

Oldest comments (0)