Solucionado (ver solução)
Solucionado
(ver solução)
5
respostas

Arrow function não funciona no element.remove()

Pessoal, alguém consegue me dizer porque esse código funciona:

let listaPacientes = document.querySelectorAll(".paciente");

listaPacientes.forEach(paciente => {
    paciente.addEventListener("dblclick", function () {
        this.remove();
    });
});

E esse não funciona:

let listaPacientes = document.querySelectorAll(".paciente");

listaPacientes.forEach(paciente => {
    paciente.addEventListener("dblclick", () => {
        this.remove();
    });
});

Retorna o seguinte erro: remove-paciente.js:5 Uncaught TypeError: this.remove is not a function at HTMLTableRowElement.paciente.addEventListener (remove-paciente.js:5)

5 respostas
solução!

Boa noite, Henrique! Como vai?

O segundo código não funciona pq nas arrows functions o this tem escope léxico e no primeiro caso tem escopo funcional (nesse caso, o this representa o elemento que gerou o evento dbclick).

Faça um teste imprimindo com console.log(this) nos dois casos e vc vai ver a diferença.

Grande abraço e bons estudos!

Oi Gabriel, tudo bom e você? Obrigado pela resposta. Pode me dizer por que o escopo muda?

Abraço!

Opa! Os escopos mudam pq são dois tipos de funções diferentes e além disso o this no JavaScript tem o seu escopo dinâmico dependendo de onde é utilizado!

As arrow functions foram introduzidas no ES6 para resolver problemas como:

class MinhaClasse {
    constructor() {
        this.meuItem = 0; // atributo
    }
    fazAlgo() {
        let lista = [0, 1, 2];
        lista.forEach(function(item) {
            if (item == this.meuItem) {  // tento acessar o atributo meuItem
                console.log('igual');
            }
        });
    }

    getMeuItem() {
        return this.meuItem;  // tento acessar o atributo meuItem
    }
}

let obj = new MinhaClasse();
console.log(obj.getMeuItem()); // imprime 0
obj.fazAlgo(); // dá erro dizendo: Cannot read property 'meuItem' of undefined

Isso acontece pq o this dentro da function não se refere ao objeto MinhaClasse como era o esperado. Pra resolver isso, antes do ES6, era preciso fazer:

fazAlgo() {
    let lista = [0, 1, 2];
    lista.forEach(function(item) {
        if (item == this.meuItem) {
            console.log('igual');
        }
    }.bind(this)); // com o método bind() eu digo que o valor do this dentro da função será o mesmo valor do this que está fora da função, ou seja, fazendo referência ao objeto criado!
}

Ou com a famosa solução utilizando uma variável that

fazAlgo() {
    let that = this;
    let lista = [0, 1, 2];
    lista.forEach(function(item) {
        if (item == that.meuItem) {
            console.log('igual');
        }
    });
}

Daí, para não ter que recorrer a essas coisas, no ES6 foram introduzidas as arrows functions que já mantém o valor do this com o valor "externo" da função sem que pra isso precisemos escrever código a mais como nos 2 exemplos anteriores. Desse modo, agora podemos fazer:

fazAlgo() {
    let lista = [0, 1, 2];
    lista.forEach(item => {
        if (item == this.meuItem) {
            console.log('igual');
        }
    });
}

Esses e outros assuntos são tratados pelo mestre Flávio em seus cursos avançados de JavaScript!

Curso JavaScript avançado I: ES6, orientação a objetos e padrões de projetos

Curso JavaScript Avançado II: ES6, orientação a objetos e padrões de projetos

Curso JavaScript Avançado III: ES6, orientação a objetos e padrões de projetos

Como vc ainda não os assistiu, indico fortemente que vc assista para que possa aprofundar ainda mais seus conhecimentos nessa linguagem!

Grande abraço e bons estudos!

Perfeito Gabriel! Muito obrigado =)

Por nada, Henrique! Sempre que tiver qualquer dúvida é só mandar aqui no fórum!

Grande abraço e bons estudos!