I was reading some documentation about javascript and stumbled upon the following code example:
var o = {
value: 1,
outer: function () {
var inner = function () {
console.log(this); //bound to global object
};
inner();
}
};
o.outer();
It outputs window
.
I cannot figure out why is the this
keyword bound to the global object (window
) instead of the parent object (outer
).
If you want to access outer
from inner
's scope, you have to pass the outer
's this
(which is just like passing outer
itself) to its local inner
function as an argument. So, as expected:
var o = {
value: 1,
outer: function () {
var inner = function (that) {
console.log(that); //bound to global object
};
inner(this);
}
};
o.outer();
outputs outer
.
Isn't it a bit of a nonsense that in outer
's scope this
is bound to the object itself (i.e. outer
), while in the inner
's scope, which is local to outer
, this
is re-bound to the global object (i.e. it overrides outer
's binding)?
The ECMAScript specs states that when entering the execution context for function code if the «caller provided thisArg» is either null or undefined, then this
is bound to the global object.
But the following:
var o = {
outer: function () {
var inner = function () {
console.log('caller is ' + arguments.callee.caller);
};
inner();
}
}
outputs the object outer
itself:
caller is function () {
var inner = function () {
console.log('caller is ' + arguments.callee.caller);
};
inner();
}
On a side, but probably relevant, note:
In strict mode the first code snippet outputs undefined
instead of window.
It's a new feature that introduced in ES6 and is called arrow function. The left part denotes the input of a function and the right part the output of that function.
Nested functions A function is called “nested” when it is created inside another function. It is easily possible to do this with JavaScript.
“This” keyword refers to an object that is executing the current piece of code. It references the object that is executing the current function. If the function being referenced is a regular function, “this” references the global object.
By default, "this" is a reference to the object on which a particular function is called (in JavaScript all functions are bound to an object). We can, however, use call() and apply() to change this binding at runtime.
This is because this
is set when the function is run, not when it's defined.
For example:
var o = {
func: function(){
console.log(this);
}
};
When you call o.func()
, you are doing so in the context o
, so it works as expected.
Now let's say you do this:
var f = o.func;
f();
This will not work as expected. This is because when you call f()
, it doesn't have any context attached to it, so this
will be window
.
You can fix this by using .call
to change the value of this
.
var f = o.func;
f.call(o); // sets `this` to `o` when calling it
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