this en JavaScript : comprendre à quoi il fait référence

En JavaScript, this ne dépend pas de l'endroit où la fonction est écrite mais de la façon dont elle est appelée : cinq formes d'appel, cinq résultats.
3 min de lecture
Believemy logo

Aucun mot-clé du langage ne provoque autant de confusion. La raison est simple : dans la plupart des langages, this est fixé à l'écriture, alors qu'en JavaScript il est déterminé à l'appel.

Une même fonction peut donc voir plusieurs valeurs différentes selon la manière dont on la déclenche.


Définition

this désigne l'objet sur lequel une fonction est en train d'être appelée. Ce n'est pas l'objet dans lequel la fonction est écrite, c'est celui qui figure à gauche du point au moment de l'appel.

JAVASCRIPT
const compteur = {
  total: 0,
  incrementer() {
    this.total += 1;
    return this.total;
  },
};

console.log(compteur.incrementer());   // 1
console.log(compteur.incrementer());   // 2

Ici, compteur se trouve à gauche du point, donc this le désigne, et l'incrément porte bien sur cet objet.


Cinq formes d'appel, cinq résultats

Le tableau ci-dessous se lit comme une grille : cherchez la forme de l'appel, lisez la valeur obtenue.

Forme de l'appelValeur de this
objet.methode()L'objet placé avant le point
fonction() dans un moduleundefined
new Modele()L'instance en cours de fabrication
fonction.call(cible)La cible passée en premier argument
Fonction fléchéeCelui du code environnant

La deuxième ligne mérite une précision : en mode strict ou dans un module, un appel sans objet donne undefined. Dans un vieux script non modulaire, la même ligne donne l'objet global.


Le piège de la méthode détachée

Ranger une méthode dans une variable ou la passer en argument coupe le lien avec son objet. C'est la cause la plus fréquente des erreurs sur ce mot-clé.

JAVASCRIPT
const compteur = {
  total: 0,
  incrementer() { this.total += 1; return this.total; },
};

const detachee = compteur.incrementer;
try {
  detachee();                 // plus rien à gauche du point
} catch (erreur) {
  console.log(erreur.name);   // TypeError
}

const liee = compteur.incrementer.bind(compteur);
console.log(liee());          // 1

La méthode bind fabrique une nouvelle fonction dont la valeur est figée définitivement. L'autre solution, souvent plus lisible, consiste à envelopper l'appel dans une fonction fléchée : elle n'a pas de valeur propre et prend celle du code qui l'entoure.

JAVASCRIPT
const minuteur = {
  secondes: 0,
  demarrer() {
    setTimeout(() => {
      this.secondes += 1;
      console.log(this.secondes);   // 1
    }, 0);
  },
};

minuteur.demarrer();

Avec une function classique à la place de la flèche, l'addition donnerait NaN : c'est setTimeout qui appelle la fonction, sans objet à gauche du point.


Questions fréquentes

Question

Pourquoi une fonction fléchée n'a-t-elle pas de this ?

Parce qu'elle n'en reçoit jamais à l'appel : elle utilise celui du code dans lequel elle est écrite, exactement comme n'importe quelle autre variable de ce code. C'est ce qui la rend idéale à l'intérieur d'une méthode, et inadaptée pour définir une méthode elle-même, où elle irait chercher une valeur qui n'existe pas.


Question

Quelle différence entre call, apply et bind ?

call et apply appellent la fonction immédiatement en imposant la valeur, la seule différence étant la façon de passer les arguments, un par un ou dans un tableau. bind n'appelle rien : il renvoie une nouvelle fonction avec la valeur figée, à déclencher plus tard.


Question

Comment savoir ce que vaut this dans du code que je lis ?

Ne regardez pas la déclaration de la fonction, cherchez l'appel. La question à poser est toujours la même : qu'y a-t-il à gauche du point au moment où cette fonction est déclenchée. Notre formation JavaScript revient longuement sur ce mécanisme, parce qu'il conditionne la lecture de tout code orienté objet.

Termes connexes

Découvrez notre glossaire JavaScript

Tous les mots de JavaScript expliqués simplement : mots-clés, objets natifs, méthodes, erreurs et concepts. Définitions claires et exemples qui tournent, pour apprendre et pour se dépanner.

Partager cet article

Tu veux nous aider ? Fais un lien vers cet article sur tes réseaux ou encore mieux : sur ton site, dans un article ou dans ta newsletter.