Question:
In the code below, the first console.log(this)
returns the example
object (so far so good). The second console.log(this)
returns the window
object.
Why does it happen? Why, even inside an object, does let f2
go into the global context?
In my initial conception, because it is within the execution context of f1
, this
should remain the same.
let example = {
f1: function() {
console.log(this);
let f2 = function() {
console.log(this);
}
f2();
}
}
example.f1();
Answer:
Because this was not bound to this
function.
Perhaps the best way to look at this
is as an ordinary argument: it has to be initialized to some value.
When you invoke a method (invoke a function through an object), JS itself initializes this
with a reference to the object:
var obj = {
val: 10,
logValue() {
console.log(this.val);
}
}
obj.logValue();
It works, right? this
was initialized with a reference to obj
, so this.val
is the same as obj.val
.
Now what happens if we unbind the function from obj
?
var obj = {
val: 10,
logValue() {
console.log(this.val);
}
}
var func = obj.logValue;
func();
It doesn't work anymore. this
no longer refers to obj
, it refers to window
, as the function has not been bound to obj
.
Note, binding can be done manually as well:
var obj = {
val: 10,
logValue() {
console.log(this.val);
}
}
var func = obj.logValue;
func.bind(obj)();
This is basically what happens when you do obj.logValue()
, the binding is done automatically for you.
If you're familiar with Python, it's similar to the way the first argument is automatically initialized with an object reference when you invoke a function through an object.