Wednesday, July 1, 2015

the scope of this in JavaScript

Kyle Simpson's book this & OBJECT PROTOTYPES lists four varieties of bindings for this:

  1. Default Binding just looks up the call-stack for the call-site. One step up the history of calls from the spot at hand is where this is defined. As the name implies, this is the default.
    function sigourneyWeaver() {
       alert("The computer says: " + this.message);
    }
    var message = "Hello World";
    sigourneyWeaver();

     
  2. Implicit Binding has one fishing for this.whatever at an object's properties.
    function sigourneyWeaver() {
       alert("The computer says: " + this.message);
    }
    var computer = {
       message: "Hello World",
       operator: sigourneyWeaver
    }
    computer.operator();

     
  3. Explicit Binding is the .call stuff.
    function sigourneyWeaver() {
       alert("The computer says: " + this.message);
    }
    var computer = {
       message: "Hello World"
    }
    sigourneyWeaver.call(computer);

     
  4. new Binding lets you sidestep the usual truth that when using this in a function, you are not referring to the scope of the function itself.
    function sigourneyWeaver(message) {
       this.reiteration = "The computer says: " + message;
    }
    var noomiRapace = new sigourneyWeaver("Hello World");
    alert(noomiRapace.reiteration);

     

The third of the four, Explicit Binding, is the most interesting. When a primative is handed into a function, behind the scenes it is boxed. The boxing allows for the primative to be created as if newed up. A string is handed to the function such that makes it into the function as if assigned by a = new String("Hello World"); approach. Such affects this like so:

function sigourneyWeaver() {
   alert("The computer says: " + this);
}
sigourneyWeaver.call("Hello World");

 
 

In the concept of Hard Binding the function called with Explicit Binding is always called from a wrapper function to which variables to be passed on are handed in. This keeps the scope of this from behaving unexpectedly. One interesting thing about the example in the book is that it revealed to me that functions have an "arguments" variable which is an array of all variables handed into the function even if or without regard to if they are not defined at function's signature. Observe:

function sigourneyWeaver() {
   alert("The computer says: " + this);
}
function rickMoranis() {
   sigourneyWeaver.call(arguments[0]);
}
rickMoranis("Hello World");

 
 

Now imagine the protected function was swappable at the wrapping function like so:

function sigourneyWeaver() {
   alert("The computer says: " + this);
}
function rickMoranis(gateKeeper, message) {
   gateKeeper.call(message);
}
rickMoranis(sigourneyWeaver, "Hello World");

 
 

Alright, because this is a common pattern for Explicit/Hard Binding JavaScript makes the code immediately above a bit easier to repeat with .bind like so:

function sigourneyWeaver() {
   alert("The computer says: " + this);
}
var rickMoranis = sigourneyWeaver.bind("Hello World");
rickMoranis();

No comments:

Post a Comment