Aller au contenu

Décorateurs JavaScript, call et apply

Les décorateurs JavaScript et les méthodes call/apply sont essentiels pour gérer le contexte des fonctions et étendre le comportement des classes. Ce guide explique comment les utiliser efficacement grâce à des exemples pratiques.

Comprendre les décorateurs JavaScript

Les décorateurs offrent un moyen dynamique d'observer, de modifier ou de remplacer les déclarations et membres de classe. La proposition de décorateurs est actuellement au stade 3. Bien que la syntaxe moderne soit standardisée, de nombreuses bases de code et tutoriels existants utilisent encore la syntaxe héritée, qui nécessite un transpileur comme Babel.

Que sont les décorateurs ?

Au fond, les décorateurs sont des fonctions qui vous permettent d'ajouter de nouvelles fonctionnalités aux éléments de classe (méthodes, accesseurs, propriétés) de manière déclarative. Au moment de l'exécution, ils enveloppent la méthode ou la propriété d'origine, interceptant les appels ou modifiant leur configuration avant l'instanciation de la classe. Ils sont appliqués directement avant la définition de l'élément de classe, offrant une syntaxe expressive pour modifier le comportement.

Utilisation des décorateurs

Pour utiliser un décorateur, vous préfixez la fonction décoratrice par un symbole @ et la placez au-dessus de l'élément de classe que vous souhaitez modifier. Voici un exemple basique :


Avertissement : La syntaxe des décorateurs hérités ci-dessous est dépréciée et nécessite un transpileur. La syntaxe moderne (stade 3) est standardisée et recommandée pour les nouveaux projets.

javascript
function log(target, name, descriptor) {
  const original = descriptor.value;
  if (typeof original === 'function') {
    descriptor.value = function(...args) {
      console.log(`Calling ${name} with`, args);
      return original.apply(this, args);
    }
  }
  return descriptor;
}

class MyClass {
  @log
  doSomething(arg) {
    // Method body
  }
}

Ce décorateur log affichera un message dans la console chaque fois que la méthode doSomething est appelée, y compris les arguments qui lui sont passés.

Voici l'équivalent moderne du stade 3. Dans la spécification du stade 3, target pour les décorateurs de méthode fait référence à la fonction de méthode d'origine sur le prototype, donc original.apply(this, args) l'invoque correctement. Le retour d'une nouvelle fonction remplace la méthode d'origine. Les décorateurs peuvent également être appliqués aux champs et accesseurs de classe, bien que leur initialisation et leur gestion des descripteurs diffèrent légèrement selon le type d'élément.

javascript
function log(target, context) {
  const original = target;
  return function(...args) {
    console.log(`Calling ${context.name} with`, args);
    return original.apply(this, args);
  };
}

class MyClass {
  @log
  doSomething(arg) {
    // Method body
  }
}

Exploiter call et apply

Les méthodes call et apply sont des outils essentiels en JavaScript pour spécifier le contexte this d'une fonction et l'invoquer. Bien qu'elles servent des objectifs similaires, leur utilisation diffère légèrement.

La méthode call

La méthode call invoque une fonction avec une valeur this donnée et des arguments fournis individuellement.

Exemple de call :


Output appears here after Run.

La méthode apply

À l'inverse, apply invoque la fonction avec une valeur this donnée et des arguments fournis sous forme de tableau.

Exemple de apply :


Output appears here after Run.

call et apply sont tous deux puissants dans les scénarios où le contexte de this doit être défini explicitement ou lors du travail avec des fonctions acceptant un nombre variable d'arguments.

Remarque : Contrairement à call et apply, qui invoquent la fonction immédiatement, bind retourne une nouvelle fonction avec le contexte this définitivement fixé, permettant une exécution différée.

javascript
const boundGreet = greet.bind(person);
boundGreet(); // Output: "Hello, John"

Applications pratiques

Les décorateurs simplifient l'ajout de comportement aux objets sans modifier le code d'origine, favorisant une conception plus propre et plus modulaire. De même, call et apply offrent une flexibilité dans l'invoquation des fonctions, ce qui est crucial pour maintenir le contexte this correct ou gérer les fonctions à nombre variable d'arguments.

Conclusion

Les décorateurs et les méthodes call/apply fournissent des outils puissants pour écrire du JavaScript concis, flexible et efficace. Maîtriser ces concepts permet une meilleure réutilisation du code, une abstraction plus poussée et une gestion du contexte dans des applications complexes.

Pratique

Quelles affirmations décrivent correctement l'utilisation et les différences entre les méthodes `call` et `apply` en JavaScript ?

Trouvez-vous cela utile?

Aperçu dual-run — comparez avec les routes Symfony en production.