En JavaScript, this fait partie de ces mots clés qui paraissent simples au début, puis deviennent flous dès qu’on change un peu de contexte. On croit souvent que this désigne toujours l’objet dans lequel on se trouve. En réalité, il dépend surtout de la façon dont une fonction est appelée. C’est ce décalage qui crée la plupart des incompréhensions.
Dit autrement, this n’est pas fixé une bonne fois pour toutes au moment où l’on écrit une fonction. Il est résolu au moment de l’exécution. C’est pour ça qu’un même morceau de code peut se comporter différemment selon l’endroit d’où il est invoqué. Si vous avez déjà lu un article sur les fonctions JavaScript, vous pouvez aussi jeter un oeil à cet autre billet sur JavaScript, qui complète bien le sujet.
Contenu
Pourquoi this perturbe autant de développeurs ?
Le vrai piège, c’est qu’on confond facilement this avec le contexte lexical. Dans beaucoup d’autres situations en JavaScript, ce qui compte est l’endroit où le code est écrit. Pour this, ce n’est pas la bonne intuition. Ce qui compte, c’est l’appel.
Prenons un cas simple :
const utilisateur = {
nom: 'Yvon',
afficherNom() {
console.log(this.nom);
}
};
utilisateur.afficherNom(); // 'Yvon'
Ici, tout va bien. La méthode est appelée via utilisateur.afficherNom(), donc this pointe sur utilisateur. Beaucoup de développeurs s’arrêtent à cette première lecture et pensent que this référence toujours l’objet qui contient la méthode. Le problème arrive dès qu’on détache la fonction :
const fn = utilisateur.afficherNom;
fn(); // undefined dans la plupart des cas modernes
Cette fois, la fonction n’est plus appelée comme méthode d’un objet. Elle est appelée seule. Le lien avec utilisateur a disparu, et this ne vaut plus ce qu’on imaginait.
Ce que this représente vraiment
const personne = {
nom: "Yvon",
parler() {
console.log(this.nom)
}
}
Pour bien comprendre, il faut retenir une règle simple : this dépend de la forme d’appel.
- Appel simple :
fn()donne unthisglobal ouundefinedselon le contexte. - Appel comme méthode :
objet.fn()fait pointerthisversobjet. - Appel forcé :
call,applyetbindpermettent de choisir la valeur dethis. - Fonction fléchée : elle ne crée pas son propre
this, elle récupère celui du contexte englobant.
Cette distinction change tout. Une fonction classique peut donc être très pratique quand on veut un this dynamique, mais elle peut aussi devenir source de bugs dans un callback, un timer ou un gestionnaire d’événement mal attaché.
Si vous aimez revoir les bases avec des exemples progressifs, cet article lié peut aussi aider à remettre les concepts dans l’ordre avant de revenir sur this.
L’ancienne technique self ou that
Avant l’arrivée massive des fonctions fléchées, on utilisait souvent une astuce très répandue : stocker this dans une variable comme self ou that. L’idée était simple : capturer la bonne référence avant d’entrer dans une fonction interne.
const compteur = {
valeur: 0,
incrementer() {
const self = this;
setTimeout(function () {
self.valeur++;
console.log(self.valeur);
}, 1000);
}
};
Cette technique a longtemps été utile, surtout quand une fonction interne perdait le bon contexte. Elle marche encore, et il est bon de la connaître parce qu’on la rencontre dans beaucoup d’anciens projets. Mais aujourd’hui, elle sert surtout à comprendre l’histoire du langage et à lire du code existant.
La version moderne avec les fonctions fléchées
const objet = {
nom: "Yvon",
init() {
const self = this
setTimeout(function () {
console.log(self.nom)
}, 100)
}
}
Dans la plupart des cas modernes, une fonction fléchée rend l’intention plus claire :
const compteur = {
valeur: 0,
incrementer() {
setTimeout(() => {
this.valeur++;
console.log(this.valeur);
}, 1000);
}
};
Ici, la fonction fléchée ne redéfinit pas this. Elle reprend celui de incrementer(). Résultat : pas besoin de self, pas besoin de bricoler, et le code se lit plus facilement.
Attention quand même : cela ne veut pas dire que les fonctions fléchées sont toujours meilleures. Si vous définissez une méthode d’objet directement en fléché, vous pouvez obtenir l’effet inverse de celui recherché, car la fonction fléchée ne recevra pas le this de l’objet au moment de l’appel.
const utilisateur = {
nom: 'Yvon',
afficherNom: () => {
console.log(this.nom);
}
};
Dans ce cas, this ne représente pas utilisateur. C’est une erreur fréquente chez les débutants.
Un réflexe utile pour éviter les erreurs
Quand vous voyez this, ne demandez pas d’abord « dans quel objet suis-je ? » Demandez plutôt : « comment cette fonction est-elle appelée ? » Ce réflexe évite beaucoup de confusion. Il aide aussi à comprendre pourquoi deux fonctions qui se ressemblent peuvent produire des résultats différents.
En pratique, retenez trois idées. D’abord, this change de contexte selon l’appel. Ensuite, la technique self ou that reste utile pour lire du vieux code. Enfin, les fonctions fléchées simplifient souvent la situation, sans régler tous les cas à votre place.
Une fois cette logique intégrée, les comportements de this paraissent beaucoup moins arbitraires. On commence à voir qu’il ne s’agit pas d’un mot clé capricieux, mais d’une règle d’appel qu’il faut apprendre à reconnaître dans le code courant.