The reason behind this is that this
binding is determined based on where it was called not where it is declared.
There are four rules according to You don't Know JS books
Default Binding
example
let world = "hello world"
function hello() {
console.log(this.world)
console.log(this)
}
hello() // prints hello world and global object
//the call site is on the global environment
Implicit Binding
example
let object1 = {
world: "I am being called from object1 site ",
hello: hello
}
let object2 = {
world: "I am in 2",
object1: object1
}
object2.object1.hello() //will print " I am being called from object1 site because of the taking the object that is closest level to the function and that is objec1"
obj.hello() // print "I am being called from object1 site and object1 properties
Explicit Binding
This occurs when you are 'explicit' about the object you want this
to refer to and in this case you use call, apply and bind (which is more stronger in binding this to expected object)
Example
hello.call(object1) in this case this will refer to object1. In an event where call
or apply
does not work you can use bind to make a hard bind .That is why you would see this pattern a lot
Let say you want to refer to the person object
const person = {
talk() {
setTimeout(
function () {
console.log(this);
}.bind(this),
1000
);
},
};
person.talk(); // `this` will refer to the person object
Let say you want to refer to global object in Node
let globalObject = globalThis;
const person = {
talk() {
setTimeout(
function () {
console.log(this);
}.bind(globalObject),
1000
);
},
};
person.talk(); // this will refer to global object
New Binding: this is using keyword new to create an object
Example let b = new life()
To determine this
in code you have to know how it was used in the call site and they take precedence over in this order: new binding > explicit binding > implicit binding > default binding