DEV Community

NIBRAS NAZAR for Innovation Incubator

Posted on • Originally published at Medium on

JavaScript Execution Context

‘JavaScript is the world’s most misunderstood programming language.’

- Douglas Crockford

This article is for js beginners to understand the concept of order of execution. for that, we need to talk about Execution Contexts.

Prerequisite: knowledge about

  1. Objects
  2. Functions

Execution Contexts

All JavaScript code runs in an environment, and these environments are called Execution Contexts. Imagine an Execution Context as a container or a simple box which stores variables, and in which a piece of our code is evaluated and executed. We can associate each Execution Context as an Object

Global Execution Context is the default Execution Context in which all the code that is not inside of any function is executed. Global execution context is associated with the global object, in the case of a browser, it will be a window object.

firstName == window.firstName //true

Each time a function is called, a new Execution Context( variables and statement to be executed of that function ) is created and stacked up in the Execution Stack. An Execution Stack is the one that holds the Execution Contexts of the currently invoked functions.

An active Execution Context is the one that is at the top of the Execution Stack.

let’s see an example

var name = 'Ron';

function first(){
  var a = 'hello';
  second(); // calling fuction 'second()' 
  var x = a + name;
}

function second(){
  var b = 'hi';
  var y = b + name;
}

first(); // calling function 'first();'

  1. In the beginning, the Execution stack contains Global Execution Context. The variable ‘name’ and function declarations belong to this Global Execution Context.

  1. When the function ‘first()’ is called, its Execution Context gets on to the top of the current Execution Context (global execution context ) and becomes the active execution context.

  1. Function ‘first’ then calls the ‘second()’ before completing its execution and execution context of ‘second’ becomes active.

  1. When function ‘second’ finishes its execution, its Execution Context gets popped off from the Execution Stack and Execution Context of ‘first’ becomes active and continues with its remaining task.

  1. similarly when function ‘first’ finishes its task, its execution context gets popped off from the stack.

As said before, Execution Context can be considered as an object and this object has three properties:

  1. Variable Object
  2. Scope Chain
  3. “This” Variable

Variable Object  _— _which will contain function arguments in a variable declaration as well as function declarations.

Scope Chain  — contains the current variable objects as well as the variable objects of all its parents;

“This” Variable  — reference to the current Execution Context.

When a function is called, a new execution context is put on top of the execution stack, and this happens in two phases:

  1. Creation Phase
  2. Execution Phase

Creation Phase

The Creation Phase includes:

  1. creation of the variable object ( VO ),
  2. creation of the scope chain,
  3. determines the value of “this” variable.

Creation of Variable Object ( VO ) :

  • The argument object is created, which contains all the arguments that were passed into the function.
  • The code is scanned for function declarations , and for each function, a property is created in a variable object, pointing to that function.
  • the code is scanned for variable declarations , and for each variable, a property is created in a variable object and set to “ undefined ”.

The last two points are called “ Hoisting ”.Functions and variables are hoisted in JavaScript, which means that they are available before the execution phase actually starts.

let's see an example….

calculateAge(1996); // function call

function calculateAge(year) { // function declaration
    console.log(2020 - year);
}

output : 
24

The ‘calculateAge’ function is available to use it before the function declaration due to Hoisting.

Creation of Scope Chain :

  • A Scope defines the access to a variable from a place
  • Each function creates a scope: space or an environment in which the variables that it defines are accessible.
  • Lexical scoping: a function that is lexically within another function gets access to a scope of the outer function.

let’s see an example …

var a = 'Hello!';
first();

function first() {
    var b = 'Hi!';
    second();

    function second() {
        var c = 'Hey!';
        console.log(a + b + c);
    }
}

output:
 Hello!Hi!Hey!

Here the function ‘second’ can access the global variables and variables from its parent function ‘first’.

In the creation phase, each execution context object will get exact scope chain, which is basically all the variable objects ( VO )that an execution context has access to, because the variable object (VO) stores all the defined variables and functions. In this example, in the second scope, we have access to the variable object, of the second functions, of the first function, and to global variable object

The global scope will never ever have access to the variables b or c unless we return the values from the functions. So locally scoped variables are not visible to their parent scopes.

The execution stack is different from the scope chain. An Execution Stack is an order in which functions are called but the scope chain is the order in which functions are written in the code

You can find the difference with the example given below

var a = 'Hello!';
first();

function first() {
    var b = 'Hi!';
    second();

function second() {
        var c = 'Hey!';
        third()
    }
}

function third() { //on top of execution stack
  var d = 'John';
  console.log(a+b+c+d); //here b and c not accessible by ScopeChain        
}

Determining ‘this’ Variable :

‘this’ variable is a variable that each and every Execution Context gets and points to an object

  • In a Regular Function Call , the ‘this’ keyword simply points at the global object (The window object. in the browser )
  • In a method call , ‘this’ variable points to the object that is calling the method.
  • the ‘this’ keyword is not assigned a value until the function where it is defined is actually called.

let’s see two examples here….

example 1 :

calculateAge(1985);

function calculateAge(year) {
    console.log(2020 - year);
    console.log(this); // output : window object{}
}

here ‘this’ Variable is the window object because it is a regular function call and object that the function ‘calculateAge’ is attached to is the global object.

example 2 :

var john = {
    name: 'John',
    yearOfBirth: 1990,
    calculateAge: function() {
        console.log(this); // output : john object {}
        console.log(2016 - this.yearOfBirth);
    }
}

john.calculateAge();

here ‘this’ keyword refers to the object that called the method which is the john object. In method call, ‘this’ variable always points to the object that is calling the method.

Execution Phase

The Execution phase includes the execution of the code and the function that generated the current execution context.

The End

One of the best course to learn JS: https://www.udemy.com/share/101WfeAEMecFdRRnwD/


Top comments (0)