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:
- 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
bind
the this
value: (function(){ CODE GOES HERE }).bind(this)();
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…