Comportamento do this
em funções
O valor de this
em uma função JavaScript depende do contexto em que a função é chamada. Em alguns casos, esse comportamento pode levar a problemas, especialmente ao usar funções como métodos de objetos.
Problema
No exemplo abaixo, a palavra-chave this
não faz referência ao objeto Calculadora
, mas sim ao objeto Document
, uma vez que o método addEventListener
pertence a esse objeto.
function criarCalculadora() {
return {
display: document.querySelector(".display"),
iniciar() {
this.cliqueBotoes();
},
cliqueBotoes() {
document.addEventListener("click", function (e) {
const el = e.target;
console.log(this); // document
if (el.classList.contains("btn-num")) {
this.btnParaDisplay(el.innerText);
}
});
},
btnParaDisplay(valor) {
this.display.value += valor;
},
};
}
const calculadora = criarCalculadora();
calculadora.iniciar();
Solução
Existem duas maneiras comuns de resolver o problema de referência this
:
Utilizar a Função bind()
Isso sobrescreve a referência this
da função para o objeto Calculadora
.
function criarCalculadora() {
return {
display: document.querySelector(".display"),
iniciar() {
this.cliqueBotoes();
},
cliqueBotoes() {
document.addEventListener(
"click",
function (e) {
const el = e.target;
console.log(this);
if (el.classList.contains("btn-num")) {
this.btnParaDisplay(el.innerText);
}
}.bind(this)
);
},
btnParaDisplay(valor) {
this.display.value += valor;
},
};
}
const calculadora = criarCalculadora();
calculadora.iniciar();
Utilizar Arrow Function
Uma arrow function não possui seu próprio this
, portanto, ela herda o valor de this
do contexto superior, ou seja, referencia o objeto no qual foi definida.
function criarCalculadora() {
return {
display: document.querySelector(".display"),
iniciar() {
this.cliqueBotoes();
},
cliqueBotoes() {
document.addEventListener("click", (e) => {
const el = e.target;
console.log(this);
if (el.classList.contains("btn-num")) {
this.btnParaDisplay(el.innerText);
}
});
},
btnParaDisplay(valor) {
this.display.value += valor;
},
};
}
const calculadora = criarCalculadora();
calculadora.iniciar();
Ambas as abordagens têm seus casos de uso, e a escolha entre elas depende do contexto específico em que você está trabalhando.