Sunday, August 7, 2016

JavaScript: Quick thoughts on *this* in inner functions

For insight into function invocation and the global scope, please note following code:


    var scope_example = "global";
    var outerDude1 = function(){
        var that = this;
        var scope_example = "outer Function";
        var scope_example_as_well = "outer Function";
        var innerDude = function() {
            var scope_example = "inner Function";
            console.log("1: " + scope_example);
            console.log("1: " + this.scope_example);
            console.log("1: " + that.scope_example);
            console.log("1: " + scope_example_as_well);
        };
        innerDude();
    };
    outerDude1();


When run, this produces:
1: inner Function
1: global
1: global
1: outer Function

  1. Of course, the first console.log will see the local variable
  2. The second console.log is using this refers to the global scope.  Douglas Crockford calls this a mistake in the design of the language as it is more useful and intuitive to have this include variables just outside this inner function. I could not agree more.
  3. The third console.log also has access to this global variable because we gave that a pointer to the this in the outer scope.
  4. It’s important to remember that by not using this, we still have access to the variables in the function scope just outside of this inner function
But the previous example is not the typical way to use that.  We usually use it to access public properties of the outer function from within the inner function like this:

        
    var scope_example = "global";
    var outerDude2 = function(){
        var that = this;
        this.scope_example = "outer Function Public";  // Very different here
        var scope_example_as_well = "outer Function Private";
        var innerDude = function() {
            var scope_example = "inner Function";
            console.log("2: " + scope_example);
            console.log("2: " + this.scope_example);
            console.log("2: " + that.scope_example);
            console.log("2: " + scope_example_as_well);
        };
        innerDude();
    };
    outerDude2();


When run, this produces:
2: inner Function
2: outer Function Public
2: outer Function Public
2: outer Function Private

The major difference here is that (in line 4) we tie the scope_example variable to this.  In that context, this is the global this and updates the variable defined in the first line.  Therefore both 3rd and 4th console.log(s) are referring to this global variable with the now misleading value of “outer Function Public.”


Another great example is here: JS Fiddle

No comments:

Post a Comment