Compilation and Interpretation

To most of us it looks like JavaScript is an interpretor based language because we do see the direct source code in most of the web pages but it is actually not. JavaScript runtime engine compiles the source code into intermediate binary code on the fly and then interprets it.

Compilation Phase
The minute we create a function it actually creates an object behind the scenes and a variable by name function name binding to this object.

 
var a = 10;
function myFn(x) {
  var b = 20;
  var c = x;
  console.log(a+b+c);
}
myFn(30);

** If you notice carefully there are 5 variables (3 explicitly declared and 1 implicit myFn, 1 implicit param)
During compilation
line #1 // ‘a’ is put in global scope
line #2 // implicit var ‘myFn’ is put in global scope
line #2 // ‘x’ is put in myFn scope
line #3 // ‘b’ is put in myFn scope
line #4 // ‘c’ is put in myFn scope
Note that compilation phase does not look at RHS, it only looks at the LHS, i.e, declarations “var a”. Scope chains are created at compilation step.

Execution Phase
This phase ignores the declaration part and only looks at “a = 10” instead of “var a = 10”. It also refers to the scope chains created in compilation scope to find which variable to use where.
line #1 // Interpretor assigns var the value 10, similarly other variables at line 3 and 4
line #5 // It tries to search for ‘console’ var declaration in myFn scope, since its not declared, interpretor goes one level up and searches again (.. so on till it finds var console) and then invokes the log on it.

Global Scope Problem: Lets look at how interpretor interprets this code

var a = 10; // looks at 'a' from global scope from compilation step and assigns value 10
function myFn() {
  var b = a; // search for 'a' in myFn scope, its not declared, goes one level up to Global Scope and find it and uses it
  console.log(d); // search for 'd' in myFn scope, its not declared, goes one level up to Global Scope and still does not finds it and errors out. Note that it errors out because its a READ operation
  c = 100; // search for 'c' in myFn scope, its not declared, goes one level up to Global Scope and still does not finds it, instead of erroring out it creates variable 'c' because we are writing to it (NOT READING). Interesting thing is that, as the interpretor went up the scope levels all the way to Global Scope, it creates the variable in Global Scope itself eventhough this is the line responsible for the creation of this variable. Compiler skipped to identify the scope if the variable because it does not have the declaration with 'var'
}

Some surprising JS behaviors

var a = 10;
function outer() {
  var b = a;
  console.log(b);
  function inner() {
    var b = 20;
    var c = b;
    console.log(c);
  }
  inner();
}
outer();

This will have 3 scopes at compilation step and interpretor goes and resolves all variables from the compilation at the time of interpretation and runs the program. Its all good, lets see the same program with some minor modifications.

var a = 10;
function outer() {
  var b = a;
  console.log(b);
  function inner() {
    var c = b;
    console.log(c);
    var b = 20;
  }
  inner();
}
outer();

This will print ‘c’ as ‘undefined’ but NOT ’10’ as a typical programmer thinks. WHY???
#1 – The order of ‘var’ really does not matter in JS because compilation happens prior to interpretation.
#2 – There are two steps involved in every JS program, first step is compilation and the nest is interpretation. The problem here is that, compilation only looks at vars and interpretation does not look at vars at all.

At Interpretation phase
line #: When it looks at var ‘b’, it asks the ‘inner’ scope for this variable and its not initialized by the interpretor YET, its still available in ‘inner’ scope because its declared with var. And hence we are trying access a variable which is declared but not yet initialized, it gives us ‘undefined’. This is also referred to the problem of HOISTING

Problem of Hoisting
All the var declarations in JS code are moved/hoisted to the top in each of the execution scopes no matter where they are declared. Because of this reason we get ‘undefined’ as seen above. This is also the problem with function expressions (NOT WITH FUNCTION DECLARATION)

fnA();
function fnA() {
  console.log('hello')
}
Would run fine, BUT
fnA();
var fnA = function() {
  console.log('hello')
}

would give an error because the function expression is defined after execution command is invoked by the interpretor

Using strict mode
Its introduced in ECMA5 and this will not allow JS to initialize variables without declaring them.

"use strict"; // this should be the first line
var myName = "tekmarathon";
myname = "test"; // this will throw runtime error

Note: Strict mode can be applied to a function as well.

Reference
https://www.youtube.com/watch?v=9T3AIM3JMss&list=PLqq-6Pq4lTTZ_LyvzfrndUOkIvOF4y-_c&index=16
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

Mawazo

Mostly technology with occasional sprinkling of other random thoughts

amintabar

Amir Amintabar's personal page

101 Books

Reading my way through Time Magazine's 100 Greatest Novels since 1923 (plus Ulysses)

Seek, Plunnge and more...

My words, my world...

ARRM Foundation

Do not wait for leaders; do it alone, person to person - Mother Teresa

Executive Management

An unexamined life is not worth living – Socrates

javaproffesionals

A topnotch WordPress.com site

thehandwritinganalyst

Just another WordPress.com site

coding algorithms

"An approximate answer to the right problem is worth a good deal more than an exact answer to an approximate problem." -- John Tukey

%d bloggers like this: