Sobes.tech
Middle

Comment interdire la modification du contexte en JavaScript?

sobes.tech IA

Réponse de l'IA

En JavaScript, le contexte d'exécution d'une fonction (la valeur de this) est déterminé dynamiquement au moment de l'appel. Il n'est pas possible d'empêcher complètement sa modification dans un sens absolu, mais il est possible de contrôler ou de fixer le contexte de différentes manières :

  1. Méthodes call, apply, bind :

    • call et apply permettent d'appeler une fonction avec un contexte et des arguments explicites (séparés dans call, sous forme de tableau dans apply).
    • bind crée une nouvelle fonction liée, dans laquelle this est fixé de manière rigide à la valeur spécifiée au moment de sa création, indépendamment de l'appel ultérieur. C'est la méthode la plus efficace pour "interdire" le changement de contexte pour les appels futurs.
    // Exemple avec bind
    const obj = { value: 42 };
    function showValue() {
      console.log(this.value);
    }
    
    const boundShowValue = showValue.bind(obj);
    
    boundShowValue(); // Affichera 42
    boundShowValue.call({ value: 100 }); // Affichera toujours 42, le contexte est fixé
    
  2. Fonctions fléchées (Arrow Functions) :

    • Les fonctions fléchées n'ont pas leur propre this. elles capturent this du contexte environnant (lexicographique) au moment de leur définition.
    • Le contexte d'une fonction fléchée ne peut pas être modifié avec call, apply ou bind.
    // Exemple avec fonction fléchée
    const outerObj = { name: 'Outer' };
    
    class MyClass {
      constructor() {
        this.className = 'MyClass';
        this.showNameArrow = () => {
          // `this` ici capture `this` du constructeur ou du contexte de définition de `MyClass`
          console.log(this.className);
        };
      }
    
      showNameRegular() {
        // `this` ici est déterminé lors de l'appel
        console.log(this.className);
      }
    }
    
    const instance = new MyClass();
    instance.showNameArrow(); // Affichera 'MyClass'
    
    const anotherObj = { className: 'Another' };
    const boundArrow = instance.showNameArrow.bind(anotherObj); // Tentative de changer le contexte
    boundArrow(); // Affichera toujours 'MyClass', le contexte de la fonction fléchée est immuable
    
    instance.showNameRegular.call(anotherObj); // Affichera 'Another', le contexte de la fonction normale change
    

En résumé, "interdire le changement de contexte" se comprend mieux comme fixer fermement le contexte. Pour cela, on utilise bind pour les fonctions normales et la liaison lexicographique naturelle pour les fonctions fléchées. Les fonctions fléchées sont dans ce sens plus "inflexibles".