2023-08-24 22:45 Temps de lecture : 10 min

Comprendre le mot clé JavaScript « this »

Quelle est la signification du mot-clé `this` en JavaScript ? Comment l'exploiter efficacement dans vos projets JavaScript ? Ces interrogations reviennent fréquemment, aussi bien chez les novices que chez certains développeurs JavaScript chevronnés.

Si vous vous posez ces questions, cet article est pour vous. Il explorera les références de `this` dans divers contextes, tout en vous familiarisant avec les pièges à éviter pour prévenir confusions et erreurs dans votre code.

`this` dans le contexte global

Dans un contexte global, `this` pointe vers l'objet `window`, à condition qu'il ne soit pas utilisé à l'intérieur d'une fonction. Le contexte global désigne l'utilisation de `this` en dehors de toute fonction.

  if(true) {
    console.log(this)
  }
  let i = 2
  while(i < 10) {
    console.log(this)
    i++
  }

L'exécution du code précédent affichera l'objet `window`.

`this` dans les fonctions internes (méthodes)

Lorsqu'il est employé dans une fonction, `this` fait référence à l'objet auquel cette fonction est associée. L'exception se présente lorsqu'il est utilisé dans une fonction autonome, auquel cas il renvoie l'objet `window`. Examinons quelques exemples.

Dans l'exemple qui suit, la fonction `sayName` est contenue dans l'objet `me` (il s'agit donc d'une méthode). Dans ce type de situation, `this` désigne l'objet qui englobe la fonction.

  function sayName() {
    return `Mon nom est ${this.name}`
  }
  const me = {
    name: "Kingsley",
    sayName: sayName
  }
  console.log(me.sayName())

`this` représente ici l'objet `me`. Par conséquent, `this.name` dans la méthode `sayName` est équivalent à `me.name`.

On peut aussi considérer que la valeur de `this` est ce qui se trouve à gauche de la fonction au moment de son appel. Cela implique que vous pouvez réutiliser la fonction `sayName` dans différents objets, et elle fera référence à chaque fois à un contexte distinct.

Comme mentionné précédemment, `this` renvoie l'objet `window` lorsqu'il est employé dans une fonction isolée. En effet, une fonction autonome est par défaut liée à l'objet `window` :

  function talk() {
    return this
  }
  talk()

L'appel de `talk()` revient à appeler `window.talk()`, et tout ce qui se trouve à gauche de la fonction deviendra automatiquement `this`.

Il est à noter que le comportement de `this` diffère en mode strict de JavaScript (il renvoie `undefined`). C'est un point important à garder à l'esprit lors de l'utilisation de bibliothèques d'interface utilisateur qui exploitent le mode strict (par exemple, React).

Utilisation de `this` avec Function.bind()

Il peut arriver que vous ne puissiez pas simplement ajouter une fonction à un objet en tant que méthode (comme dans la section précédente).

Peut-être que l'objet ne vous appartient pas, car il provient d'une bibliothèque. L'objet est immuable, et vous ne pouvez donc pas le modifier directement. Dans de tels cas, la méthode `Function.bind()` permet d'exécuter l'instruction de fonction indépendamment de l'objet.

Dans l'exemple ci-dessous, la fonction `sayName` n'est pas une méthode de l'objet `me`, mais vous la liez à l'aide de la fonction `bind()` :

  function sayName() {
    return `Mon nom est ${this.name}`
  }
  const me = {
    name: "Kingsley"
  }
  const meTalk = sayName.bind(me)
  meTalk()

L'objet que vous passez en argument de `bind()` sera utilisé comme valeur de `this` lors de cet appel de fonction.

En résumé, vous pouvez utiliser `bind()` sur n'importe quelle fonction pour lui attacher un nouveau contexte (un objet). Cet objet va alors redéfinir la signification de `this` dans cette fonction.

Utilisation de `this` avec Function.call()

Que se passe-t-il si vous ne voulez pas renvoyer une nouvelle fonction, mais simplement appeler la fonction après l'avoir liée à son contexte ? La solution est d'utiliser la méthode `call()` :

  function sayName() {
    return `Mon nom est ${this.name}`
  }
  const me = {
    name: "Kingsley"
  }
  sayName.call(me)

La méthode `call()` exécute la fonction immédiatement, sans créer de nouvelle fonction.

Si la fonction nécessite des paramètres, vous pouvez les transmettre via la méthode `call()`. Dans l'exemple qui suit, vous passez la langue à la fonction `sayName()` afin de pouvoir l'utiliser pour afficher différents messages de manière conditionnelle :

  function sayName(lang) {
    if (lang === "en") {
      return `Mon nom est ${this.name}`
    } else if (lang === "it") {
      return `Io sono ${this.name}`
    }
  }
  const me = {
    name: "Kingsley"
  }
  sayName.call(me, 'en')
  sayName.call(me, 'it')

Comme vous pouvez le constater, vous pouvez passer n'importe quel paramètre de votre choix à la fonction en tant que deuxième argument de la méthode `call()`. Vous pouvez également passer autant de paramètres que vous le souhaitez.

La méthode `apply()` est très similaire à `call()` et `bind()`. La seule différence est que vous passez plusieurs arguments séparés par une virgule avec `call()`, tandis que vous les passez sous forme de tableau avec `apply()`.

En conclusion, `bind()`, `call()` et `apply()` vous permettent tous d'appeler des fonctions avec un objet différent, sans relation entre eux (c'est-à-dire que la fonction n'est pas une méthode de l'objet).

`this` dans les fonctions constructeurs

Si vous appelez une fonction avec le mot-clé `new`, un objet `this` est créé et renvoyé :

  function person(name){
    this.name = name
  }
  const me = new person("Kingsley")
  const her = new person("Sarah")
  const him = new person("Jake")
  me.name
  her.name
  him.name

Dans le code ci-dessus, vous avez créé trois objets distincts à partir de la même fonction. Le mot-clé `new` établit automatiquement une liaison entre l'objet en cours de création et le mot-clé `this` à l'intérieur de la fonction.

`this` dans les fonctions de rappel

Les fonctions de rappel (callbacks) diffèrent des fonctions ordinaires. Les callbacks sont des fonctions que vous transmettez en argument à une autre fonction, de sorte qu'elles soient exécutées après la fin de l'exécution de la fonction principale.

Le mot-clé `this` se réfère à un contexte totalement différent lorsqu'il est utilisé dans des fonctions de rappel :

  function person(name){
    this.name = name
    setTimeout(function() {
      console.log(this)
    }, 1000)
  }
  const me = new person("Kingsley")

Après une seconde d'appel de la fonction constructeur de `person` et de création d'un nouvel objet `me`, l'objet `window` sera affiché comme valeur de `this`. Ainsi, lorsqu'il est utilisé dans un callback, `this` fait référence à l'objet `window` et non à l'objet "construit".

Il existe deux manières de résoudre ce problème. La première méthode consiste à utiliser `bind()` pour lier la fonction `person` à l'objet nouvellement créé :

  function person(name){
    this.name = name
    setTimeout(function() {
      console.log(this)
    }.bind(this), 1000)
  }
  const me = new person("Kingsley")

Avec cette modification, `this` dans le callback pointera vers le même `this` que la fonction constructeur (l'objet `me`).

La deuxième solution pour régler ce problème dans les callbacks consiste à recourir aux fonctions fléchées.

`this` dans les fonctions fléchées

Les fonctions fléchées diffèrent des fonctions ordinaires. Vous pouvez convertir votre callback en fonction fléchée. Avec les fonctions fléchées, `bind()` n'est plus nécessaire car elles se lient automatiquement à l'objet nouvellement créé :

  function person(name){
    this.name = name
    setTimeout(() => {
      console.log(this)
    }, 1000)
  }
  const me = new person("Kingsley")

Approfondir vos connaissances en JavaScript

Vous avez désormais une compréhension complète du mot-clé `this` et de sa signification dans les différents contextes de JavaScript. Si vous débutez avec JavaScript, il est fortement recommandé d'apprendre les bases de ce langage et son fonctionnement.

Auteur
France

Rédacteur tech, guides pratiques et astuces numériques.