Just JavaScript - Execution Context
Written by Ian Elliot   
Monday, 29 July 2019
Article Index
Just JavaScript - Execution Context
How It Goes Wrong

Closures are logical but subtle and you need to make sure that you really understand them. This is made easier if you think about a closure as a preserved execution context.  In this extract from my recent book the emphasis is on when functions share that context.

This is an extract from the book Just JavaScript by Ian Elliot.

Buy Now: from your local Amazon

Just JavaScript 
An Idiomatic Approach

JustJavaScriptSmall

A Radical Look At JavaScript

 

Most books on JavaScript either compare it to the better known class based languages such as Java or C++ and even go on to show you how to make it look like the one of these.

Just JavaScript is an experiment in telling JavaScript's story "just as it is" without trying to apologise for its lack of class or some other feature. The broad features of the story are very clear but some of the small details may need working out along the way - hence the use of the term "experiment". Read on, but don't assume that you are just reading an account of Java, C++ or C# translated to JavaScript - you need to think about things in a new way. 

Just JavaScript is a radical look at the language without apologies.

Contents

  1. JavaScript – Essentially Different
  2. In The Beginning Was The Object
  3. Real World Objects 
  4. The Function Object
          Extract - The Function Object
          Extract - Function Object Self Reference
  5. The Object Expression 
  6. Function Scope, Lifetime & Closure
    Extract Scope, Lifetime & Closure
    Extract Execution Context ***NEW!
  7. Parameters, Returns and Destructuring
         Extract - Parameters, and Destructuring 
  8. How Functions Become Methods
  9. Object Construction
         Extract: - Object Factories 
  10. The Prototype
         Extract - ES2015 Class and Extends 
  11. Inheritance and Type
  12. The Search For Type 
  13. Property Checking

Buy Now: from your local Amazon

Also by Ian Elliot 
JavaScript Async: Events, Callbacks, Promises and Async Await
Just jQuery: The Core UI 
Just jQuery: Events, Async & AJAX  

<ASIN:1871962579>

<ASIN:1871962560>

<ASIN:1871962501>

<ASIN:1871962528>

In this chapter we look at some of the more advanced ideas involved in JavaScript functions leading up to the very useful, but often misunderstood, idea of closure. Most of the complexities arise from the simple fact that once you have a Function object you can execute its code and this code can in turn create variables and most importantly additional Function objects.

It is assumed that you already know the basics of closure and why they are a natural consequence of function objects existing independently of their execution. The following are in the chapter but not in this extract:

  • Scope and the Execution Context
  • Lifetimes
  • Closures

Execution Contexts Are Shared

There are some slightly subtle points that we have to cover to make sure that closure is not misused.

For example, what happens when there is more than one inner function and hence more than one closure?

The key idea is that there is only ever one execution context for a given Function invocation and any Functions created within that execution context share it.

That is, each time a Function is executed an execution context comes into existence consisting of all of the variables that are in scope. Any Functions created while the original Function is executing have that single execution context as their closure – i.e. it is shared.

Notice, however, that each time a Function is executed a new execution context is created along with new inner Function objects.

Consider the following code:

  var myFunction=function(){
                   var myVar=1;
                   this.myF1=function(){
                               alert(myVar);
                             };
                    myVar=2;
                    this.myF2=function(){
                                alert(myVar);
                              };
                    myVar=3;
                 };

 

You can see that myFunction creates two inner functions, myF1 and myF2, and the execution context has a single local variable in it i.e. myVar. The question is, what value does myVar have in myF1 and myF2?

myFunction();
myF1();
myF2();

You should have no problem in predicting that you see the value 3 twice. Both functions share the same execution context and the same myVar which has the value it was assigned when myFunction concludes.

Now consider the slightly more complicated case:

  var myFunction=function(){
                   var myVar=1;
                   this.myF1=function(){
                               alert(myVar);
                               myVar=2;
                             };
                   this.myF2=function(){
                               alert(myVar);
                               myVar=3;
                             };
                  };

This is almost the same, but now myFunction sets myVar to 1 which is its value in the execution context when either of myF1 or myF2 is called. So if you use:

  myFunction();
  myF1();
  myF2();

you will see 1 displayed, and then myF1 sets myVar to 2 which is what you see displayed by myF2.

That is, myF1 and myF2 share the same execution context and hence they have the variable myVar in common.

Variables that functions have access to due to closure are often referred to as “private” variables because they cannot be accessed outside of the function, but they are more correctly thought of as shared private variables.

Now compare this to what happens if you call a Function more than once to produce multiple inner functions:

var myFunction = function () {
                   var myVar = 1;
                   return function (a) {
                            alert(myVar);
                            myVar++;
                           };
                 };

In this case myFunction returns a reference to a Function object that it creates. This is a more usual way for an inner function to persist after its outer function has finished running. The execution context of this function includes the variable myVar which the function displays and then increments.

What do you think you see if you try:

var myF1=myFunction();
var myF2=myFunction();
myF1();
myF1();
myF2();
myF2();

Notice that myF1 and myF2 are identical functions and they both increment myVar provided by the outer function – but is it the same myVar?

The answer is no.

You will see 1,2 followed by 1,2 rather than 1,2,3,4 because myF1 and myF2 each have their own copy of myVar. Each time myFunction is executed a new myVar is created along with a new execution context and hence a new closure. Once you realize that myVar is created anew each time myFunction is executed it becomes obvious that myF1 and myF2 cannot share the same variable.

JustJavaScripticon



Last Updated ( Monday, 29 July 2019 )