Execution Contexts and Scope Chains in Javascript

I was planning to write a post about Execution Contexts and Scope Chains, but my research found a few brilliant articles by a front-end architect named David Shariff who set it out better than I ever could:

  1. What is the Execution Context & Stack in JavaScript?
  2. The this keyword
  3. Identifier Resolution and Closures in the JavaScript Scope Chain

The trigger for my plan was some really bad information. There was an article on codeproject purporting to give answers to interview questions about Javascript. It soon became evident that the article was flawed*. In his article, the following question and answer was set out:

What do you understand by the “this” keyword in JavaScript?

Ans: “this” keyword refers to the current object like other language.

Oh dear. If he really thinks that, he is in for a lifetime of subtle bugs.

Definitely read those articles which I linked to at the top of this post. Shariff provides the foundation for understanding things like identifier resolution and closures. It’s also tremendously important to know what the this identifier is binding to at all times, otherwise you may well find yourself attempting to access things which have the value undefined.

In a response to this stackoverflow question, the poster named Daniel Trebbien included a small quiz which I am reproducing here for posterity (and because it is so good). If you cannot answer these questions, I really recommend reading the resources which I have listed at the top of this post.

(To view the answers, hover over the grey rectangle below each question.)

  1. What is the value of this at line A? Why?
    if (true) {
        // Line A
    }
    
    window
    Line A is evaluated in the initial global execution context. There’s no block scope in javascript. So the if block does not have its own local scope.
  2. What is the value of this at line B? Why?
    var obj = {
        someData: "a string"
    };
    
    function myFun() {
        // Line B
    }
    
    obj.staticFunction = myFun;
    obj.staticFunction();
    
    obj
    When calling a method on an object, this is bound to that object.
  3. What is the value of this at line C? Why?
    var obj = {
        myMethod : function () {
            // Line C
        }
    };
    var myFun = obj.myMethod;
    myFun();
    
    window
    In this example, the JavaScript interpreter enters function code, but because myFun is not called on an object, this is bound to window.
  4. What is the value of this at line D? Why?
    function myFun() {
    	// Line D
    }
    
    var obj = {
    	myMethod : function () {
    	eval("myFun()");
    	}
    };
    
    obj.myMethod();
    
    window
    This one was tricky. When evaluating the eval code, this is obj. However, in the eval code, myFun is not called on an object, so this is set to window for the call.
  5. What is the value of this at line E?
    function myFun() {
        // Line E
    }
    var obj = {
        someData: "a string"
    };
    myFun.call(obj);
    
    obj
    The line myFun.call(obj); is invoking the special built-in function Function.prototype.call(), which accepts thisArg as the first argument. myFun is being called as if it is a method on obj.

As an added bonus, I’ve devised two more quiz questions which are kinda tricky (but simple when you reason it through):

  1. If the following code runs, what is the value of this at line A? Line B? Why?
    //  room is object where nested function is a lambda (or function expression)
    var room = {
        capacity: 10,
        exits: 2,
        count: 0,
        addPerson: function (name) {
            //  Line A
            this.count += 1;
    
            var nestedFunction = function (nameOfPerson) {
                //  Line B
                this.person = nameOfPerson;
            }(name);
        }
    };
    room.addPerson('dave');
    

    Line A – room
    As addPerson is being invoked as a method on the room object, the this variable is bound to the room object.

    Line B – window
    The anonymous function is being executed (self-invoked) as a function and not as a method of any object. That being the case, the this variable is bound to window.

  2. If the following code runs, what is the value of this at line C? Line D? Why?
    var person = 'Bob';
    
    var room = {
    	capacity: 10,
    	exits: 2,
    	count: 0,
    	addPerson: function (name) {
    		//  Line C
    		this.count += 1;
    
    		var nestedFunction = function (nameOfPerson) {
    			//  Line D
    			this.person = nameOfPerson;
    		};
    
    		return nestedFunction;
    	}
    };
    
    var otherRoom = {
    
      person: 'dave'
    
    };
    
    otherRoom.changePersonName = room.addPerson('');
    otherRoom.changePersonName('Joe');
    

    Line C – room
    Again, as addPerson is being invoked as a method on the room object, the this variable is bound to the room object. Things get a bit more interesting when we look at line D.

    Line D – otherRoom
    In this case, the anonymous function is being returned by the addPerson method, and it is being assigned to the changePersonName member of otherRoom. When changePersonName is invoked, it is done so as a method of otherRoom.

There’s another pretty cool resource I found on execution context which can be found in this this sample chapter of the book Even Faster Websites. The first figure is really good but it does have one one technical mistake in it, which I have corrected. Click here to see the corrected image.

Execution Context and Scope

Num2 is not a part of the Global scope and I removed it from the Global object in the diagram

* many people post articles on codeproject to pad their resume. Unfortunately, some people don’t have any idea about what they’re writing about. And this is made worse by other people up-voting their article with 5 stars.




No Comments


You can leave the first : )



Leave a Reply

Your email address will not be published. Required fields are marked *