Sobes.tech
Middle

Wie verhindert man die Änderung des Kontexts in JavaScript?

sobes.tech KI

Antwort von AI

In JavaScript wird der Ausführungskontext einer Funktion (der Wert von this) dynamisch zum Zeitpunkt des Aufrufs bestimmt. Es ist nicht möglich, seine Änderung im absoluten Sinne vollständig zu verhindern, aber man kann den Kontext auf verschiedene Weisen kontrollieren oder fixieren:

  1. Methoden call, apply, bind:

    • call und apply erlauben es, eine Funktion mit explizitem Kontext und Argumenten aufzurufen (bei call getrennt, bei apply als Array).
    • bind erstellt eine neue gebundene Funktion, bei der this fest auf den angegebenen Wert bei der Erstellung fixiert ist, unabhängig vom späteren Aufruf. Dies ist die effektivste Methode, um "die Änderung des Kontexts" für zukünftige Aufrufe zu "verbieten".
    // Beispiel mit bind
    const obj = { value: 42 };
    function showValue() {
      console.log(this.value);
    }
    
    const boundShowValue = showValue.bind(obj);
    
    boundShowValue(); // Gibt 42 aus
    boundShowValue.call({ value: 100 }); // Gibt immer noch 42 aus, der Kontext ist fixiert
    
  2. Arrow-Funktionen:

    • Arrow-Funktionen haben kein eigenes this. Sie erfassen this aus der umgebenden (lexikalischen) Umgebung zum Zeitpunkt ihrer Definition.
    • Der Kontext einer Arrow-Funktion kann nicht mit call, apply oder bind geändert werden.
    // Beispiel mit Arrow-Funktion
    const outerObj = { name: 'Outer' };
    
    class MyClass {
      constructor() {
        this.className = 'MyClass';
        this.showNameArrow = () => {
          // `this` hier erfasst `this` aus dem Konstruktor oder dem Definitionskontext von `MyClass`
          console.log(this.className);
        };
      }
    
      showNameRegular() {
        // `this` wird bei Aufruf bestimmt
        console.log(this.className);
      }
    }
    
    const instance = new MyClass();
    instance.showNameArrow(); // Gibt 'MyClass' aus
    
    const anotherObj = { className: 'Another' };
    const boundArrow = instance.showNameArrow.bind(anotherObj); // Versuch, den Kontext zu ändern
    boundArrow(); // Gibt immer noch 'MyClass' aus, der Kontext der Pfeilfunktion ist unveränderlich
    
    instance.showNameRegular.call(anotherObj); // Gibt 'Another' aus, der Kontext der normalen Funktion ändert sich
    

Kurz gesagt, "das Ändern des Kontexts zu verbieten" ist besser als fester Fixierung des Kontexts zu verstehen. Dafür werden bind für normale Funktionen und die natürliche lexikalische Bindung für Pfeilfunktionen verwendet. Pfeilfunktionen sind in diesem Sinne "unerschütterlicher".