Sobes.tech
Middle

Cum se interzice modificarea contextului în JavaScript?

sobes.tech AI

Răspuns de la AI

În JavaScript, contextul de execuție al unei funcții (valoarea this) este determinată dinamic în momentul apelului. Nu se poate împiedica complet schimbarea sa în sens absolut, dar se poate controla sau fixa contextul în diferite moduri:

  1. Metodele call, apply, bind:

    • call și apply permit apelarea unei funcții cu un context și argumente explicite (call cu argumente separate, apply cu un array).
    • bind creează o nouă funcție legată, în care this este fixat la momentul creării, indiferent de apelul ulterior. Aceasta este cea mai eficientă metodă de a "interzice" schimbarea contextului pentru apelurile viitoare.
    // Exemplu cu bind
    const obj = { value: 42 };
    function showValue() {
      console.log(this.value);
    }
    
    const boundShowValue = showValue.bind(obj);
    
    boundShowValue(); // Va afișa 42
    boundShowValue.call({ value: 100 }); // Va afișa în continuare 42, contextul este fixat
    
  2. Funcțiile săgeată (Arrow Functions):

    • Funcțiile săgeată nu au propriul this. ele capturează this din mediul înconjurător (lexicografic) în momentul definirii.
    • Contextul unei funcții săgeată nu poate fi schimbat cu call, apply sau bind.
    // Exemplu cu funcție săgeată
    const outerObj = { name: 'Outer' };
    
    class MyClass {
      constructor() {
        this.className = 'MyClass';
        this.showNameArrow = () => {
          // `this` aici capturează `this` din constructor sau din mediul de definire
          console.log(this.className);
        };
      }
    
      showNameRegular() {
        // `this` aici este determinat la apelare
        console.log(this.className);
      }
    }
    
    const instance = new MyClass();
    instance.showNameArrow(); // Va afișa 'MyClass'
    
    const anotherObj = { className: 'Another' };
    const boundArrow = instance.showNameArrow.bind(anotherObj); // Tentativă de schimbare a contextului
    boundArrow(); // În continuare va afișa 'MyClass', contextul funcției săgeată este imuabil
    
    instance.showNameRegular.call(anotherObj); // Va afișa 'Another', contextul funcției normale se schimbă
    

Pe scurt, "interzicerea schimbării contextului" este mai bine înțeleasă ca fixarea fermă a contextului. Pentru aceasta, se folosesc bind pentru funcțiile normale și legarea lexicală naturală pentru funcțiile săgeată. Funcțiile săgeată în acest sens sunt mai "inflexibile".