Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why IIFE this keyword refers to window object..?

When I run the below IFFE, why does the this keyword refer to the window object and not to a variable?

var a = {
 printThis : function () {
 console.log('printThis', this);
  var inner = (function () {
    console.log('inner', this);
   })();
  }
};

a.printThis(); 

Result in the following output:

printThis **an object**

inner **window object**   <-- why..?

var a = {
  printThis: function() {
    console.log('printThis', this);
    var inner = (function() {
      console.log('inner', this);
    })();
  }
};

a.printThis();
like image 876
Mr. A Avatar asked May 27 '16 10:05

Mr. A


1 Answers

Consider the following example:

var a = {};
var b = {};
a.hello = function() { console.log(this); };
b.hello = a.hello;

In most programming languages, b.hello() would print a since they base this on where the function is. The function is in a, so this is a. Makes sense, right?

However, JavaScript is a bit different in that regard. Instead of where it is, it's based on how it was called. b.hello() calls hello on b, thus this is set to b. This also makes sense since JavaScript doesn't really have a concept of "where" a function is (unlike methods in, say, Java, which are always tied to a specific class), and it's hard to determine that a is where it "is".

So, foo.bar() will always set this to foo for the purposes of this call to bar (unless one has used bind or similar to bind this to a specific value in advance).

Now, an IIFE is invoked on... nothing, really. It's not a foo.bar() situation, it's just a bar() where bar is your function expression. In cases like this where there's no foo, it defaults to the window object.

There are two simple workarounds:

  1. Create a variable outside the IIFE containing the value you´re interested in: var that = this; and use that instead of this in the IIFE, or
  2. bind the this value: (function(){ CODE GOES HERE }).bind(this)();
like image 196
BambooleanLogic Avatar answered Sep 21 '22 10:09

BambooleanLogic