TL;DR - this
doesn't work like you think it should.
Read more here, here and here.
The this
(otherwise known as context) of a function is determined at call time, not at function definition time. This is widely known as this
being dynamically bound, and variables from closure being lexically bound.
var obj = outer();
obj();
Calls outer
with this = window
(or global
in the case of Node.js) because you are not in strict mode (otherwise, this = undefined
). outer
doesn't use this
, so this doesn't impact it greatly.
outer
then returns a function (innerFunc
), and you assign it to obj
. You then call obj
, again, with this = window
(because you didn't specify anything other with .bind()
or .call()
or .apply()
).
You then log this.inner
which is equivalent to window.inner
which is undefined
unless you happen to have a global variable named inner
with some value.
The value of this
, then, is determined by the caller.
If you had invoked obj
like so:
obj.call({inner: 42}); // first argument to fn.call() is the context
You would have seen 42 in your console, regardless of how the function was defined.
A way to mitigate this and retain control over your this
is to either use fn.bind()
or an arrow function.