Sobes.tech
Junior

Como alterar o contexto de uma função em JavaScript?

sobes.tech IA

Resposta da IA

No JavaScript, o contexto de execução de uma função (o valor de this) pode ser alterado de várias maneiras:

  1. call(): Executa uma função com um valor this especificado e argumentos passados individualmente separados por vírgulas.

    // function.call(thisArg, arg1, arg2, ...)
    function greet(name) {
      console.log(`Olá, ${name}! Eu sou ${this.type}`);
    }
    
    const obj = { type: 'objeto' };
    
    greet.call(obj, 'Aline'); // Olá, Aline! Eu sou objeto
    
  2. apply(): Executa uma função com um valor this especificado e argumentos passados em forma de array ou objeto semelhante a array.

    // function.apply(thisArg, [argsArray])
    function sum(a, b) {
      console.log(`${this.name}: ${a + b}`);
    }
    
    const context = { name: 'Calculadora' };
    const numbers = [5, 10];
    
    sum.apply(context, numbers); // Calculadora: 15
    
  3. bind(): Cria uma nova função "ligada" a um valor this especificado. A função original não é executada imediatamente.

    // function.bind(thisArg, arg1, arg2, ...)
    const user = { name: 'Bob' };
    
    function sayHello() {
      console.log(`O meu nome é ${this.name}`);
    }
    
    const boundSayHello = sayHello.bind(user);
    
    boundSayHello(); // O meu nome é Bob
    
  4. Funções arrow (=>): As funções arrow não têm seu próprio contexto this. Elas capturam this do ambiente léxico (do escopo pai onde foram definidas).

    class MyClass {
      constructor() {
        this.value = 'valor da classe';
        // A função arrow mantém o contexto da classe
        this.logValue = () => {
          console.log(this.value);
        };
      }
    }
    
    const instance = new MyClass();
    const method = instance.logValue;
    
    method(); // valor da classe (o contexto é mantido)
    
    // Comparar com uma função normal sem bind
    class OutraClasse {
        constructor() {
            this.value = 'outro valor';
            this.logValue = function() {
                console.log(this.value); // 'this' será window ou undefined em modo estrito
            };
        }
    }
    
    const outraInstancia = new OutraClasse();
    const outroMetodo = outraInstancia.logValue;
    
    outroMetodo(); // undefined (o contexto é perdido ao chamar como função separada)