this & "binding"
Qui suis-je ?
🧐
😱
1
class Customer {
2
3
constructor(firstName, lastName) {
4
this.firstName = firstName;
5
this.lastName = lastName;
6
}
7
8
sayHi() {
9
console.log('Hi ' + this.firstName);
10
}
11
12
sayHiLater() {
13
setTimeout(function () {
14
this.sayHi();
15
}, 1000);
16
}
17
18
}
19
20
const customer = new Customer('Foo', 'BAR');
21
22
customer.sayHiLater(); // ???
Copied!
1
class Customer {
2
3
constructor(firstName, lastName) {
4
this.firstName = firstName;
5
this.lastName = lastName;
6
}
7
8
sayHi() {
9
console.log('Hi ' + this.firstName);
10
}
11
12
sayHiLater() {
13
setTimeout(function () {
14
this.sayHi();
15
}, 1000);
16
}
17
18
}
19
20
const customer = new Customer('Foo', 'BAR');
21
22
customer.sayHiLater(); // TypeError: this.sayHi is not a function
Copied!

Binding

La fonction de callback utilisée avec setTimeout n'est pas "bound" à notre instance de Customer. De plus, setTimeout espère nous aider en "bindant" l'objet timeout qu'il retourne à notre fonction de callback.
1
const timeout = setTimeout(function () {
2
console.log(this === timeout); // true
3
});
Copied!
Pour lutter contre ce comportement... m#@d!k... déstabilisant, nous pouvons "binder" notre instance de Customer à la fonction de callback.

The hacky way

1
class Customer {
2
3
constructor(firstName, lastName) {
4
this.firstName = firstName;
5
this.lastName = lastName;
6
}
7
8
sayHi() {
9
console.log('Hi ' + this.firstName);
10
}
11
12
sayHiLater() {
13
setTimeout(function () {
14
this.sayHi();
15
}.bind(this), 1000);
16
}
17
18
}
Copied!

The other hacky way

1
class Customer {
2
3
constructor(firstName, lastName) {
4
this.firstName = firstName;
5
this.lastName = lastName;
6
}
7
8
sayHi() {
9
console.log('Hi ' + this.firstName);
10
}
11
12
sayHiLater() {
13
const _this = this;
14
setTimeout(function () {
15
_this.sayHi();
16
}, 1000);
17
}
18
19
}
Copied!

Solution idéale

Pour la solution idéale, rendez-vous au prochain chapitre.