Sobes.tech
Middle

Como proibir a alteração de contexto em JavaScript?

sobes.tech IA

Resposta da IA

No JavaScript, o contexto de execução de uma função (o valor de this) é determinado dinamicamente no momento da chamada. Não é possível impedir completamente sua alteração em um sentido absoluto, mas é possível controlar ou fixar o contexto de várias maneiras:

  1. Métodos call, apply, bind:

    • call e apply permitem chamar uma função com um contexto e argumentos explícitos (separados em call, em forma de array em apply).
    • bind cria uma nova função ligada, na qual this é fixado de forma rígida ao valor especificado no momento de sua criação, independentemente da chamada posterior. Esta é a forma mais eficaz de "proibir" a mudança de contexto para chamadas futuras.
    // Exemplo com bind
    const obj = { value: 42 };
    function showValue() {
      console.log(this.value);
    }
    
    const boundShowValue = showValue.bind(obj);
    
    boundShowValue(); // Mostrará 42
    boundShowValue.call({ value: 100 }); // Ainda assim mostrará 42, o contexto está fixado
    
  2. Funções de seta (Arrow Functions):

    • As funções de seta não têm seu próprio this. Elas capturam this do ambiente circundante (lexicográfico) no momento de sua definição.
    • O contexto de uma função de seta não pode ser alterado usando call, apply ou bind.
    // Exemplo com função de seta
    const outerObj = { name: 'Outer' };
    
    class MyClass {
      constructor() {
        this.className = 'MyClass';
        this.showNameArrow = () => {
          // `this` aqui captura `this` do construtor ou do escopo de definição de `MyClass`
          console.log(this.className);
        };
      }
    
      showNameRegular() {
        // `this` aqui é determinado na chamada
        console.log(this.className);
      }
    }
    
    const instance = new MyClass();
    instance.showNameArrow(); // Mostrará 'MyClass'
    
    const anotherObj = { className: 'Another' };
    const boundArrow = instance.showNameArrow.bind(anotherObj); // Tentativa de mudar o contexto
    boundArrow(); // Ainda assim mostrará 'MyClass', o contexto da função de seta é imutável
    
    instance.showNameRegular.call(anotherObj); // Mostrará 'Another', o contexto da função normal muda
    

Resumindo, "proibir a mudança de contexto" é melhor entendido como fixar firmemente o contexto. Para isso, usam-se bind para funções normais e a ligação léxica natural para funções de seta. As funções de seta neste sentido são mais "inquebráveis".