While delving into some documentation on javascript, I came across the following code snippet:
var o = {
value: 1,
outer: function () {
var inner = function () {
console.log(this); //bound to global object
};
inner();
}
};
o.outer();
This piece of code outputs window
.
I'm puzzled as to why the this keyword is bound to the global object (window
) rather than the parent object (outer
). To access outer
from the scope of inner
, you need to pass the this
of outer
(essentially passing outer
itself) as an argument. So, this modified snippet:
var o = {
value: 1,
outer: function () {
var inner = function (that) {
console.log(that); //bound to global object
};
inner(this);
}
};
o.outer();
now outputs outer
.
It seems strange that in the scope of outer
, this
is linked to the object itself (i.e.
outer</code), but within the local scope of <code>inner
(contained within outer
), this
shifts back to the global object (effectively overriding outer
's binding).
The ECMAScript specifications state that if the «caller provided thisArg» upon entering a function's execution context is either null or undefined, then this
is associated with the global object.
However, consider this snippet:
var o = {
outer: function () {
var inner = function () {
console.log('caller is ' + arguments.callee.caller);
};
inner();
}
}
surprisingly outputs the object outer
itself:
caller is function () {
var inner = function () {
console.log('caller is ' + arguments.callee.caller);
};
inner();
}
An additional, yet possibly related, observation:
In strict mode, the initial code snippet yields undefined
instead of window.