Sobes.tech
Middle

Jak zabronić zmiany kontekstu w JavaScript?

sobes.tech AI

Odpowiedź od AI

W JavaScript kontekst wykonania funkcji (wartość this) jest określany dynamicznie w momencie wywołania. Nie można całkowicie zapobiec jego zmianie w sensie absolutnym, ale można kontrolować lub ustalić kontekst na różne sposoby:

  1. Metody call, apply, bind:

    • call i apply pozwalają wywołać funkcję z jawnie określonym kontekstem i argumentami (oddzielnie w call, jako tablica w apply).
    • bind tworzy nową funkcję powiązaną, w której this jest sztywno ustalony na wskazaną wartość w momencie tworzenia, niezależnie od późniejszego wywołania. To najskuteczniejszy sposób "zabronienia" zmiany kontekstu dla przyszłych wywołań.
    // Przykład z bind
    const obj = { value: 42 };
    function showValue() {
      console.log(this.value);
    }
    
    const boundShowValue = showValue.bind(obj);
    
    boundShowValue(); // Wyświetli 42
    boundShowValue.call({ value: 100 }); // Wciąż wyświetli 42, kontekst jest ustalony
    
  2. Funkcje strzałkowe (Arrow Functions):

    • Funkcje strzałkowe nie mają własnego this. przechwytują this z otaczającego (lexikalnego) zakresu w czasie ich definiowania.
    • Kontekst funkcji strzałkowej nie może być zmieniony za pomocą call, apply czy bind.
    // Przykład z funkcją strzałkową
    const outerObj = { name: 'Outer' };
    
    class MyClass {
      constructor() {
        this.className = 'MyClass';
        this.showNameArrow = () => {
          // `this` tutaj przechwytuje `this` z konstruktora lub zakresu definicji `MyClass`
          console.log(this.className);
        };
      }
    
      showNameRegular() {
        // `this` tutaj jest ustalany podczas wywołania
        console.log(this.className);
      }
    }
    
    const instance = new MyClass();
    instance.showNameArrow(); // Wyświetli 'MyClass'
    
    const anotherObj = { className: 'Another' };
    const boundArrow = instance.showNameArrow.bind(anotherObj); // Próba zmiany kontekstu
    boundArrow(); // Wciąż wyświetli 'MyClass', kontekst funkcji strzałkowej jest niezmienny
    
    instance.showNameRegular.call(anotherObj); // Wyświetli 'Another', kontekst zwykłej funkcji się zmienia
    

Podsumowując, "zabranie zmiany kontekstu" najlepiej rozumieć jako twarde przypięcie kontekstu. Do tego służy bind dla funkcji zwykłych i naturalne leksykalne wiązanie dla funkcji strzałkowych. Funkcje strzałkowe w tym zakresie są bardziej "niezłomne".