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