DEV Community

Cover image for Execution Context
Arafat Ahmed
Arafat Ahmed

Posted on

Execution Context

Execution Context

A theoretical environment created by JS for code evaluation and execution.

Three types of execution in JS:

  1. Global Execution Context: Primary or base execution context, has 2 main functions:
    • Create a global object
    • Attach the this value to the global object
  2. Function Execution Context: The execution context created for every function invocation (created when a function is called).
  3. Eval Execution: This is not important and I haven't clear idea about this.

Execution ( Call ) Stack

STEP 1: Global execution context is pushed on the Call stack.
STEP 2: Function execution context is created and pushed on the Call stack when a function is called.
STEP 3: The invoked function is executed and removed from the stack, along with its execution context.

Example:

function person(){
 sayName();
}

function sayName(){
 console.log("Arafat Ahmed");
}

// invoke the ‘person ‘ function
person();
Enter fullscreen mode Exit fullscreen mode

Step 1:

global()

Step 2:

person()
global()
sayName()
person()
global()

Step 3:

person()
global()
global()

Execution context

This execution is completed in 2 stages:

  1. Creation stage,
  2. Execution stage

Each step has 2 parts:

  1. Lexical environment
    • Has 3 components:
      • Environment Record
      • Ref to an outer environment
      • this binding
    • Is 2 types:
      • Declaration environment record:\ This type is used by a Lexical environment created in the Function execution context.
      • Object environment record:\ A Lexical environment mainly uses this created in the Global execution context.
  2. Variable environment
    • The structure is the same as the Lexical environment but this environment is used especially by the var variable statement.

theoretically,

   executionContext = {
       lexicalEnvironment = <ref>,
       variableEnvironment = <ref>
   }

EXAMPLE:

let a = 1;
var b = 2;

function person(){
 sayName("Hello");
}

function sayName(greeting){
 console.log(greeting + " Arafat Ahmed");
}

// invoke the "person" function
person();
Enter fullscreen mode Exit fullscreen mode

execution of this code will end in two stages

  • Creation stage
  • Execution stage

Creation Stage

globalExecutionContext:{
    "lexicalEnv":{
        environmentRecord:{
            type: "Object",
            a: <initialization>,
            person: <func>,
            sayName: <func>
        }
        outerEnv: <null>,
        thisBinding: <Global Object>
    },

    "variableEnv":{
        environmentRecord:{
            type: "Object",
            b: <initialization with "undefined">
        },
        outerEnv: <null>,
        thisBinding: <Global Object>
    }
}
Enter fullscreen mode Exit fullscreen mode

When the person function is called, a new Function execution context is created to execute the function code.

functionExecutionContext:{
    lexicalEnv:{
        environmentRecord:{
            type: "Declarative",
            args: {length: 0},
        }
        outerEnv: <Global Env>,
        thisBinding: <Global Object or undefined>
    },

    variableEnv:{
        environmentRecord:{
            type: "Declarative",
        }
        outerEnv: <Global Env>,
        thisBinding: <Global Object or undefined>
    }
}
Enter fullscreen mode Exit fullscreen mode

When the sayName function is called in person function another new Function execution context will created.

functionExecutionContext:{
    lexicalEnv:{
        environmentRecord:{
            type: "Declarative",
            args: {0: "Hello", length: 1},
        },
        outerEnv: <Global Env>,
        thisBinding: <Global Object or undefined>
    },

    variableEnv:{
        environmentRecord:{
            type: "Declarative",
        },
        outerEnv: <Person Env>,
        thisBinding: <Global Object or undefined>
    }
}
Enter fullscreen mode Exit fullscreen mode

Execution Stage

globalExecutionContext:{
    lexicalEnv:{
        environmentRecord:{
            type: "Object",
            a: 1,
            person: <func>,
            sayName: <func>
        }
        outerEnv: <null>,
        thisBinding: <Global Object>
    },

    variableEnv:{
        environmentRecord:{
            type: "Object",
            b: 2
        },
        outerEnv: <null>,
        thisBinding: <Global Object>
    }
}
Enter fullscreen mode Exit fullscreen mode
functionExecutionContext:{
    lexicalEnv:{
        environmentRecord:{
            type: "Declarative",
            args: {},
        }
        outerEnv: <Global Env>,
        thisBinding: <Global Object>
    },

    variableEnv:{
        environmentRecord:{
            type: "Declarative",
        }
        outerEnv: <Global Env>,
        thisBinding: <Global Object>
    }
}
Enter fullscreen mode Exit fullscreen mode

When the sayName function is called in person function another new Function execution context will created.

functionExecutionContext:{
    lexicalEnv:{
        environmentRecord:{
            type: "Declarative",
            args: {0: "Hello", length: 1},
        },
        outerEnv: <Global Env>,
        thisBinding: <Global Object>
    },

    variableEnv:{
        environmentRecord:{
            type: "Declarative",
        },
        outerEnv: <Person Env>,
        thisBinding: <Global Object>
    }
}
Enter fullscreen mode Exit fullscreen mode

Now, we make a little change to our previous example

let a = 1;
var b = 2;

function person(greeting){
    return function(){
         console.log(greeting + " Arafat Ahmed");
    }
}

const sayName = person("Helo");
sayName();
Enter fullscreen mode Exit fullscreen mode

What will happen?

Creation stage

globalExecutionContext:{
    "lexicalEnv":{
        environmentRecord:{
            type: "Object",
            a: <initialization>,
            person: <func>,
            sayName: <initialization>,
        }
        outerEnv: <null>,
        thisBinding: <Global Object>
    },

    "variableEnv":{
        environmentRecord:{
            type: "Object",
            b: <initialization with "undefined">
        },
        outerEnv: <null>,
        thisBinding: <Global Object>
    }
}
Enter fullscreen mode Exit fullscreen mode

Execution Stage

globalExecutionContext:{
    lexicalEnv:{
        environmentRecord:{
            type: "Object",
            a: 1,
            person: <func>,
            sayName: <func> //This will create a new context
        }
        outerEnv: <null>,
        thisBinding: <Global Object>
    },

    variableEnv:{
        environmentRecord:{
            type: "Object",
            b: 2
        },
        outerEnv: <null>,
        thisBinding: <Global Object>
    }
}
Enter fullscreen mode Exit fullscreen mode
functionExecutionContext:{
    lexicalEnv:{
        environmentRecord:{
            type: "Declarative",
            args: {0: "Hello", length: 1},
        }
        outerEnv: <Global Env>,
        thisBinding: <Global Object>
    },

    variableEnv:{
        environmentRecord:{
            type: "Declarative",
        }
        outerEnv: <Global Env>,
        thisBinding: <Global Object>
    }
}
Enter fullscreen mode Exit fullscreen mode

Here a Closure will be created because of the inner anonymous function of the parson function.

closure:{
    lexicalEnv:{
        environmentRecord:{
            type: "Declarative",
            args: { length: 0 },
        }
        outerEnv: <Person Env>,
        thisBinding: <Global Object>
    },

    variableEnv:{
        environmentRecord:{
            type: "Declarative",
        }
        outerEnv: <Global Env>,
        thisBinding: <Global Object>
    }
}
Enter fullscreen mode Exit fullscreen mode

When the execution stage will come the inner function will get access to the execution context of the outer function through its outerEnv.

Top comments (0)