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

Dúvida no uso da Reflect API

Nesse trecho do código:

this._listaNegociacoes = new Proxy(new ListaNegociacoes(), {
    get(target, prop, receiver) {
        if(['adiciona', 'esvazia'].includes(prop) && typeof(target[prop]) === typeof(Function)) {
            return function() {
                console.log(`método '${prop}' interceptado`);
                //Dúvida aqui
                Reflect.apply(target[prop], target, arguments);

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

Porque a sequencia de argumentos é Reflect.apply(target[prop], target, arguments)? Tem alguma regra para isso?

9 respostas
solução!

Tem sim. O primeiro parâmetro é o método que você quer invocar. Usamos target[prop] para termos acesso ao método. O segundo parâmetro é o contexto no qual o método será invocado, no caso target mesmo e por fim os parâmetros que serão passados para o método se houver.

Se ainda estiver com dúvida me fala que eu crio mais exercício para fixar.

Veja que fazemos target[prop] e não apenas prop porque se usarmos prop temos apenas o nome do método como string, já o primeiro nos dá acesso ao método.

Ficou claro, valeu!

Oi Thiago, elaborei um exercício de revisão para deixar ainda mais claro o Reflect.apply. Me diz o que você acha. Se estiver tranquilo, eu adiciono na plataforma:

REVISÃO Reflect.apply

Temos dois objetos criados de maneira literal por uma questão de brevidade, mas poderiam ser instâncias de uma classe:

let objeto1 = {

    nome: 'Bob'
};

let objeto2 = {

    nome: 'Leo'
}

Temos a seguinte função:

function exibeNome() {

    alert(this.nome);
}

O que acontecerá se chamarmos exibeNome? O resultado será undefined, porque o this da função, ou seja, seu contexto não possui a propriedade nome.

Agora, que tal chamarmos a função exibeNome, mas indicando que seu contexto de execução será objeto1? Vejamos:

Reflect.apply(exibeNome, objeto1, []); // exibe 'Bob'

O resultado será o alerta sendo exibido com o texto Bob. Podemos executar a função agora fazendo com que o seu this (contexto) seja objeto2:

Reflect.apply(exibeNome, objeto2, []); // exibe 'Leo'

Como Reflect.apply funciona? O primeiro parâmetro é o método ou função que desejamos invocar. O segundo parâmetro é o contexto que o método ou função adotará, ou seja, o valor que será assumido pelo this. Por fim, o último parâmetro é um array que contém todos os parâmetros que o método passado como primeiro parâmetro receberá. Como ele não recebe parâmetro nenhum, passamos um array vazio.

Vamos alterar nossa função para que recebe dois parâmetro. O primeiro será um prefixo que será adicionando no nome e o último um sufixo:

function exibeNome(prefixo, sufixo) {

    alert(prefixo + this.nome + sufixo);
}

Agora, vamos chamar o método através de Reflect.apply:

Reflect.apply(exibeNome, objeto1, ['(', ')']); // exibe '(Bob)'

Veja que agora estamos passando dois parâmetro para o método.

Muito bom esse exercício Flavio, com ele é possível fixar bem a sintaxe do Reflect.apply.

Fechou! Coloquei o exercício lá:

https://cursos.alura.com.br/course/javascript-es6-orientacao-a-objetos-parte-2/section/1/exercise/6

Oi Thiago, venho informá-lo que o módulo 3 do curso de JavaScript já foi gravado e esta na fase de criação de exercícios. Sendo assim, muito em breve ele será disponibilizado para vocês.

Ele abordará persistência de dados offline com IndexedDB, mostrará as nuâncias de Promises (inspirado nas perguntas que você postou no fórum), ensinará novos padrões de Projeto, Fetch API, transpiler com Babel e ES2015 modules e ainda truques e dicas da linguagem espalhadas pelo projeto.

Sucesso e bom estudo!

\o/

Eu estava ansioso para esse terceiro módulo. Vão ser abordados também function generators, async/awit?

Ainda não. Contudo, como você aprenderá a usar Babel como transpiler e aprenderá a configurar plugin, é meio caminho andado para usar esses recursos. Aliás, esse era o pré-requisito para poder abordar esse assunto listado por você.

O async/wait é ES2016 (ES7, no popular). É necessário transcompilar o código com um plugin experimental.