"Invocation context" and "execution context" in javascript: are we talking of the same thing?

Solution 1:

The two terms are closely related but not the same thing.

In a nutshell they define scope vs. context. Scope is about the environment that code runs in (kind of like a room - - it's about where the code is) and context is about an actual object that caused some code to be executed (like who was responsible for putting you in that room).

An "execution context" refers to the "scope chain" that is in effect when some code is running. A scope chain is a list of memory locations that should be checked (in a particular order) for identifiers (variable, constant and function names) to be resolved to a value. Since JavaScript is executed in a single-threaded environment, only one task can be executed at a time. The currently executing code (and its associated scope) define the execution context.

A simple example can be shown like this:

// This area is in the Global execution context (scope) because the code is 
// not wrapped in a function or any other kind of code block.
var x = "Global";

// "Global" is the result because the JavaScript engine will always look
// in the current scope for a declaration for the identifier in question.
// It will find a declaration for "x" right here in the Global scope, so
// that's the value it will use.
console.log(x); 

var y = "Also Global";

function parent(){
   // This area is in the "parent" execution context (scope)
   var x = "parent";

   // "parent" is the result (not "Global") because when this function is
   // executing, its scope is the most accessible. The JavaScript engine
   // looks here first to find out what "x" is. This is known as variable 
   // "hiding" because the x in the parent scope hides the x in the Global scope.
   console.log(x); 

   function child() {
      // This area is in the "child" execution context (scope)
      var x = "child";

      // "child" is the result (not "Global" or "parent") because when this 
      // function is executing, its scope is the most accessible. The 
      // JavaScript engine looks here first to find out what "x" is. This
      // x now hides the x in parent, which is hiding the x in Global.
      console.log(x); 

      // "Also Global" is the result here. First the current execution
      // context (scope) is checked for a "y" variable. There isn't one,
      // so the next scope in the scope chain (function parent) is checked.
      // There is no "y" declared there either. So, again, the next highest
      // scope in the chain (Global) is checked and that is where "y" is
      // found, so the value of that "y" is used.
      console.log(y);

      // Here, we will get "undefined". All the scopes in the chain will
      // be checked and if we go all the way up to Global and still don't
      // find a declaration for "z", there is no other scope to look in.
      console.log(z);
   }
   child();
}

parent();

The three execution contexts (scopes) shown above can be entered into in various ways. Those various ways give rise to the "invocation context".


An "invocation context" can also more accurately be called an "invocation context object" which refers to the object that was used to invoke some code. This may seem like the same thing as the "execution context", but the "invocation context" refers to the object that leads to code executing and that executing code is doing so within its own execution context (scope).

The biggest differentiating point between these two terms is understanding that the invocation context leads to the binding of the keyword this to an object for the duration of the execution context. this binding is volatile in JavaScript and the object that this binds to is subject to change as you enter into a new execution context. For all intents and purposes, this is the object that invoked some code, or this is the "invocation context".

I've written another answer that goes into more detail about how to determine what this will bind to and you can see that here.

See the following snippet for an explanation of invocation context. It illustrates one execution context (function foo), but two invocation contexts (the button and Global).

function foo() {
  // When this function is "invoked" via the button click
  // the invocation context is the button and the console will
  // log this as: [object HTMLButtonElement]
  
  // But, when the function is invoked from a direct call to foo
  // from the Global execution context, this will be bound
  // to the window object. So, in that case we'll get: [object Window]
  console.log("The 'this' object (invocation context object) is: " + this);
}

// Call foo from the Global execution context.
foo();

var btn = document.getElementById("btnTest");

// When the button is clicked, execute foo
btn.addEventListener("click", foo);
<button id="btnTest">Click Me</button>

Solution 2:

"execution context" is the official term (i.e. used by the specification) for a stack frame. As the wording says, it provides the context for the (current) execution of code, which basically consists of internal evaluation state, the function (code) that is currently evaluated, and the active variable scope. Being part of a stack, it knows where to return to when the function execution ends.

"invocation context" probably refers to the context object on which a method is invoked, i.e. the obj in obj.method(). It will become the value for this in that function. The spec doesn't use this term anywhere, what you'll find are thisArgument, thisValue and receiver. It's referred to as ThisBinding in the environment record that is part of the lexical environment (scope) that is contained in every execution context.