Saturday, March 16, 2013

Execution Context in JavaScript

Execution Context can be visualize as Environment/scope the current code is being evaluated in.
As per ECMA  - When control is transferred to ECMAScript executable code, control is entering an execution context. Active execution contexts logically form a stack. The top execution context on this logical stack is the running execution context.

Browser is a single threaded environment. Only 1 thing can happen at a time, other actions will be queued in "Execution Stack".
Every function and constructor call enters a new execution context, even if a function is calling itself recursively. Every return exits an execution context. A thrown exception, if not caught, may also exit one or more execution contexts.

Lets take an example here -
(function foo(i) {
    if (i === 3) {
        return;
    }
    else {
        foo(++i);
    }
}(0));

In the above excample foo calls itself 3 times. Hence along with the global context, it creates 4 more execution context(for i = 0,1,2,3).

Execution Context has 2 stages -
1) Create stage - function called, but not yet executed-
1.1 Create Variables, functions and arguments
a) Create the arguments object, check the context for parameters, initialize the name and value and create a reference copy.
b) For each function found, create a property in the variable object that is the exact function name, which has a reference pointer to the function in memory.
c) For each variable declaration found, create a property in the variable object that is the variable name, and initialize the value as undefined.
1.2 Create Scope chain
1.3 Create value of "this"
2) Activation/Execution stage -
Assign values, reference to functions and execute


Execution context can be visualize in following object format -
executionContextObj = {
    variableObject: { /* function arguments / parameters, inner variable and function declarations , Can also be visualize as Activation Object*/ },
    scopeChain: { /* variableObject + all parent execution context's variableObject */ },
    this: {}
}

When the JavaScript engine invokes any function, it creates a new object (Activation object) and all the local variable defined within the function and the named argument passed to the function along with ‘arguments’ object get defined as properties of this activation object. The activation object is also added to the front of the execution scope chain.
In current scenario when control enters an execution context for function code, an object called the "Activation object"(stage 1.1) is created and associated with the execution context. The activation object is initialised with a property with name arguments and attributes.
The activation object is then used as the variable object for the purposes of variable instantiation.
The activation object is purely a specification mechanism. It is impossible for an ECMA Script program to access the activation object. It can access members of the activation object, but not the activation object itself.

Here is an example -
function foo(i) {
    var a = 'hello';
    var b = function privateB() {
    };
    function c() {
    }
}
foo(22);

After stage 1 -
fooExecutionContext = {
    variableObject: { // stage 1.1
        arguments: { // stage a
            0: 22,
            length: 1
        },
        i: 22, // stage a
        c: pointer to function c() // stage b
        a: undefined, // stage c
        b: undefined  // stage c
    },
    scopeChain: { ... }, //stage 1.2
    this: { ... } // stage 1.3
}

After Stage 2 -
fooExecutionContext = {
    variableObject: {
        arguments: {
            0: 22,
            length: 1
        },
        i: 22,
        c: pointer to function c()
        a: 'hello',
        b: pointer to function privateB()
    },
    scopeChain: { ... },
    this: { ... }
}

Reference -
1) http://davidshariff.com/blog/what-is-the-execution-context-in-javascript/
2) http://bclary.com/2004/11/07/#a-10

No comments:

Post a Comment