Da trilha de JavaScript Este conceito ainda não saiu como card do dia. ir para o card de hoje

JavaScript Funções Intermediário

this e contexto

Em JavaScript, this é uma referência ao contexto de execução atual, que depende de como e onde a função é chamada, não de onde foi definida. Em funções tradicionais, this é definido no momento da chamada; já em arrow functions, this é herdado do escopo léxico onde a função foi criada. Entender isso é essencial para evitar bugs comuns, como perder o contexto ao passar métodos como callbacks.

Existem três métodos para controlar explicitamente o valor de this: call, apply e bind. call e apply invocam a função imediatamente com um this específico (a diferença está na passagem de argumentos: call recebe argumentos separados, apply recebe um array). bind retorna uma nova função com o this fixado, útil para callbacks.

Em classes, this refere-se à instância criada. Métodos de classe são funções normais e, se passados como callbacks, perdem o contexto. Para resolver, podemos usar bind no construtor ou definir métodos como arrow functions (que capturam o this da instância).

Neste card, você vai praticar esses conceitos com exemplos práticos e exercícios que simulam situações reais.

Pontos-chave

  • this em funções tradicionais depende de como a função é chamada.
  • Arrow functions não têm this próprio; herdam do escopo léxico.
  • call e apply invocam a função imediatamente com um this específico.
  • bind cria uma nova função com this fixado permanentemente.
  • Em classes, métodos perdem o contexto se passados como callbacks; use bind ou arrow functions.
this_context.js
// Exemplo de this em diferentes contextos
const pessoa = {
  nome: 'Ana',
  saudacaoTradicional: function() {
    console.log(`Olá, eu sou ${this.nome}`);
  },
  saudacaoArrow: () => {
    console.log(`Olá, eu sou ${this.nome}`); // this não é o objeto
  }
};

pessoa.saudacaoTradicional(); // this = pessoa
pessoa.saudacaoArrow(); // this = escopo externo (global ou undefined)

// Perda de contexto
const saudacao = pessoa.saudacaoTradicional;
saudacao(); // this não é mais pessoa

// call, apply, bind
function apresentar(idade, cidade) {
  console.log(`${this.nome}, ${idade} anos, de ${cidade}`);
}

apresentar.call(pessoa, 30, 'São Paulo');
apresentar.apply(pessoa, [30, 'São Paulo']);
const apresentarAna = apresentar.bind(pessoa);
apresentarAna(30, 'São Paulo');

// Classes
class Contador {
  constructor() {
    this.valor = 0;
    // this.incrementar = this.incrementar.bind(this); // descomente para corrigir
  }
  incrementar() {
    this.valor++;
    console.log(this.valor);
  }
}

const contador = new Contador();
const inc = contador.incrementar;
// inc(); // Erro: this é undefined

// Solução com arrow function no método
class ContadorArrow {
  constructor() {
    this.valor = 0;
  }
  incrementar = () => {
    this.valor++;
    console.log(this.valor);
  };
}

const contadorArrow = new ContadorArrow();
const incArrow = contadorArrow.incrementar;
incArrow(); // 1

Exercícios

  1. 1
    Fácil

    Corrigindo o contexto com bind

    Dado o objeto usuario com a propriedade nome e o método dizerOla, crie uma função saudacao que seja uma versão do método dizerOla com o this fixado no objeto usuario. Em seguida, chame saudacao() e imprima a saudação correta.

    Resolver
  2. 2
    Médio

    Call, apply e bind na prática

    Crie uma função apresentar que recebe idade e cidade e usa this.nome para montar uma frase. Depois, use call, apply e bind para invocar essa função com o objeto pessoa e os argumentos 30 e 'Rio de Janeiro'. Imprima o resultado de cada invocação.

    Resolver
  3. 3
    Desafio

    Contador com contexto preservado

    Crie uma classe Contador que possui um valor interno e um método incrementar que aumenta o valor em 1 e imprime o novo valor. O método incrementar deve funcionar mesmo quando extraído da instância (por exemplo, const inc = contador.incrementar; inc();). Implemente duas versões: uma usando bind no construtor e outra usando arrow function como método de classe. Teste ambas.

    Resolver

Continue estudando