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

Diferença entre interceptar/sobrescrever o método grita() com e sem "return function"

Olá pessoal!

Abaixo a classe e a resposta desta atividade (considerando return function):

class Pessoa {

    constructor(nome) {
        this._nome = nome;
    }

    get nome() {
        return this._nome;
    }

    set nome(nome) {
        this._nome = nome;
    }

    grita(frase) {
        return `${this._nome} grita ${frase}`;
    }
}
let pessoa = new Proxy(new Pessoa('Barney'), {

        get(target, prop, receiver) {
            if(prop == 'grita' && typeof(target[prop]) == typeof(Function)) {

                // forma 1 início
                return function() { 
                    console.log(`Interceptei o método: ${prop}, por isso estou exibindo essa mensagem!`);    
                    return Reflect.apply(target[prop], target, arguments);       
                } 
                // forma 1 fim
            }

            return Reflect.get(target, prop, receiver);
        }
});

console.log(pessoa.grita('Olá'));

E abaixo o código (forma 2) que substituí no código acima (onde estão os comentários forma 1):

                console.log(`Interceptei o método: ${prop}, por isso estou exibindo essa mensagem!`);    
                Reflect.apply(target[prop], target, arguments);   

Para mim tanto a forma 1 quanto a forma 2 geraram o mesmo resultado.

Tanto nesta atividade, quanto no vídeo que explica sobre interceptação de método, é citado a utilização de return function.

Dúvida: as duas formas estão corretas?

Questiono porque não entendi o motivo de ser necessário um return function (se puderem explicar), visto que (na minha opinião) a forma 2 é menos verbosa e seria a primeira solução que me viria à mente caso necessitasse utilizar o Proxy (não sei se a forma 1 me viria à mente).

Desde já obrigado! At.te

4 respostas

Olá pessoal!

Depois de vááários "debugs" (console.log por tudo huahua), demorou mas notei que a forma 2 (acima) não está correta. Na verdade o Reflect.apply, apesar de ser executado, não é o que faz o resultado ser igual à forma 1.

O que faz o resultado ser igual à forma 1 foi a seguinte linha, mais abaixo no código:

return Reflect.get(target, prop, receiver); 
// target = pessoa (object)
// prop = grita (function)

Porquê? Porque o retorno deste Reflect.get é a própria função/método grita, que sobrescreve/é executada no lugar do método original (que também é o método grita)!

// retorno de Reflect.get...
grita(frase) {
     return `${this._nome} grita ${frase}`;
} 

Então, corrigindo, a forma 2 (que poderia substituir a forma 1) ficaria apenas com uma linha, ou seja, apenas com o código referente à armadilha/trap em si:

console.log(`Interceptei o método: ${prop}, por isso estou exibindo essa mensagem!`);

Equipe Alura, favor apenas verifiquem/retornem se esse meu entendimento está correto e, neste caso, podem encerrar o tópico.

Desde já obrigado! At.te

Fala aí Elías, tudo bem? Vamos lá:

Na forma um existe o return functon()... para que se caia na condição:

if(prop == 'grita' && typeof(target[prop]) == typeof(Function))

Ou seja, está verificando se a propriedade chamada é grita e se grita é uma função, caso seja, é necessário retornar uma nova função que irá realizar o console e depois chamar a grita.

Porém, caso não caia na condição, está sendo apenas retornado os get's da classe.

Na forma 2, se você retirar o return function, ele irá passar por esse trecho e depois no final, também irá passar pelo Reflect.get.

Ou seja, quando realizamos o return dentro do if é para que ele não execute as demais linhas de código daquele trecho.

Espero ter ajudado.

Olá Matheus, tudo certo, e contigo?

Obrigado pelo retorno.

Sim, na forma 1 o return é para não executar linhas posteriores (neste caso o Reflect.get).

Mas o que eu queria saber é se o meu entendimento (meu 2º comentário) do "funcionamento" da forma 2 está correto, e também se esta forma 2 é uma solução viável.

At.te

solução!

Estar certo ou errado é complicado de falar, pois, se está funcionando teoricamente não está errado.

Eu gosto de falar que não é aconselhado fazer assim, pelo menos eu não faria do jeito da forma 2.

Se você está dentro do if que é uma function, para mim faz sentido retornar uma nova função (como é feito na forma 1).

E retirar os return pode empactar em alguns problemas no futuro, ou seja, executar trechos de códigos que não deveriam.

Mas, se está funcionando, tranquilo, não vejo isso como errado, apenas não recomendaria ou fazeria desse jeito (não gosto de dizer certo/errado).

Espero ter ajudado.