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
thisem funções tradicionais depende de como a função é chamada.- Arrow functions não têm
thispróprio; herdam do escopo léxico. calleapplyinvocam a função imediatamente com umthisespecífico.bindcria uma nova função comthisfixado permanentemente.- Em classes, métodos perdem o contexto se passados como callbacks; use
bindou arrow functions.
// 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