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();
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:
var that = this; and use that instead of this in the IIFE, orbind the this value: (function(){ CODE GOES HERE }).bind(this)();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With