O método Call

Neste artigo falaremos mais sobre o método call() que nos permite reaproveitar métodos em contextos (this) diferentes. No artigo tentarei explicar as coisas com a menor complexidade possível e resumirei alguns itens, então para aquele que sabem bem JavaScript por favor calma ai… rsrsrsr

Primeiro vamos entender mais sobre a chamada em si. É importante saber que ela:

  • É nativa, não precisa chamar biblioteca, framework, etc…
  • É um método das funções. Sim, se você ainda não sabia as funções são um tipo de dado que possui métodos/funções próprias;
    • Se ficou confuso, aguarde o exemplo.
  • Recebe um parâmetro que informa o seu contexto onde estarão os dados a executar;
    • Nesse caso contexto é uma função, objeto ou até o window se você estiver procurando pelo em ovo.
  • Pode receber mais parâmetros depois do this. Estes parâmetros se referem qualquer outro valor que você queira enviar para a função;

Note que eu estou usando as palavras função e método de forma alternada. Isso é porque eles são a mesma e tem mais diferença entre function e arrow function do que eles. 🙂

Exemplo básico

// Se chamar essa função do jeito que está aqui, vai exibir undefined pois this.umLocal não tem um valor atribuido a ele.
function ola(){
    console.log(`Olá ${this.umLocal}`);
}

// Agora vamos criar um objeto mais simples possível com a variavel umLocal
const teste = {
    umLocal : "MundoJS"
}

//Lembra quando eu disse que o call é um método das funções? Olhá só…
ola.call(teste);

Se você executar o código acima verá que ele exibirá Olá MundoJS no console. Vejamos o que aconteceu então:

  1. Criamos uma função chamada ola().
  2. Essa função exibe algo no console e chama o this.umLocal
  3. Sem fazer a chamada call() a função olha dentro de seu contexto (o this dela), não acha nada e exibe a mesma coisa
  4. Criamos um objeto com uma variável.
    1. Note que não precisamos dizer que é no contexto do objeto, mas está lá
  5. Invocamos o método call() da função ola passando o “teste” como novo contexto.
  6. Ao tentar executar a função, desta vez ela olha no teste e encontra a variável para usá-la no console.log()

Vejamos então mais alguns exemplos

1 – Passando os parâmetros da função:

// Desta vez ola recebe um parâmetro chamado saudacao
function ola(saudacao){
// aviso: se colocar this.saudacao ele não vai achar no call()…
// a explicação do porque sai bastante do artigo, mas se você entender bem de “this” e functions já deve ter se ligado. Caso queira saber mais, prende um comentário pedindo um tutorial sobre this
    console.log(`${saudacao} ${this.umLocal}`);
}

const teste = {
    umLocal : "Universo"
}
// O primeirpo parâmetro do call sempre é o “this”, depois disso você pode chamar todos os parâmetros da própria função.
ola.call(teste, "Olá");

2 – Usando métodos de Arrays em objetos que são listas mas não vetores.

Com o ES6 vieram diversos métodos muito uteis como o filter, forEach,reduce, etc… dai você tenta usar ele em uma lista que não é um vetor/array [] e não da certo pois eles não possuem isso.

// Erro pois é um HTMLCollection
document.getElementsByTagName("p").forEach(x => console.log(x));

// Vamos criar um objeto parecido com um vetor
let arrayLike = {
  0: "Olá",
  1: "MundoJS",
  length: 2
};

// e uma função para ser chamada no reduce()
function juntar(acc, cur){
    acc = `${acc} ${cur}`;
}

// Erro
// Motivo: O seu objeto parece um array (possui indices e length) mas não é um vetor e por isso não tem o método reduce nele
arrayLike.reduce(juntar);

// Agora se chamarmos o reduce e passarmos forçarmos ele a aceitar nosso objeto como o contextosArray.prototype.reduce.call(arrayLike, juntar);

Isso ai então pessoal, espero que o artigo ajude a matar algumas duvidas sobre o call e qualquer coisa perguntem aqui nos cometários. Até mais.