Métodos call e apply em JavaScript
No JavaScript, a função também é um objeto: um objeto Function que também possui um protótipo, propriedades e métodos. Todas as funções usadas no programa são objetos Function e possuem todas as suas propriedades e métodos.
Por exemplo, podemos criar uma função usando o construtor Function:
const square = new Function("n", "return n * n;");
console.log(square(5)); // 25O construtor Function pode receber vários parâmetros. O último parâmetro representa o próprio corpo da função como uma string. Essencialmente, a string contém código javascript. Os argumentos anteriores contêm os nomes dos parâmetros. Neste caso, define-se uma função para elevar um número ao quadrado, que possui um parâmetro n.
Entre as propriedades do objeto Function, podemos destacar as seguintes:
- arguments: um array de argumentos passados para a função
- length: define o número de argumentos que a função espera
- caller: define a função que chamou a função atual em execução
- name: o nome da função
- prototype: o protótipo da função
Usando o protótipo, podemos definir propriedades adicionais:
function sayHello() {
  console.log("Hello");
}
// alterando o protótipo para todas as funções
Function.prototype.program = "Hello World";
console.log(sayHello.program); // Hello WorldEntre os métodos, é importante mencionar os métodos call() e apply().
O método call() chama uma função com um valor de this especificado e argumentos:
function sum(x, y) {
  return x + y;
}
const result = sum.call(this, 3, 8);
console.log(result); // 11this refere-se ao objeto para o qual a função está sendo chamada: neste caso, é o objeto global window. Após this, são passados valores para os parâmetros.
Ao passar um objeto através do primeiro parâmetro, podemos referenciá-lo através da palavra-chave this:
function User(name, age) {
  this.name = name;
  this.age = age;
}
const tom = new User("Tom", 39);
function print() {
  console.log("Name:", this.name);
}
print.call(tom); // Name: TomNeste caso, apenas um valor é passado, já que a função print não aceita parâmetros. Ou seja, a função será chamada para o objeto tom.
Se não importa o objeto para o qual a função é chamada, então podemos passar o valor null:
function sum(x, y) {
  return x + y;
}
const result = sum.call(null, 3, 8);
console.log(result); // 11O método apply é semelhante ao call, que também chama uma função e como primeiro parâmetro também recebe um objeto para o qual a função é chamada. Agora, como segundo parâmetro, é passado um array de argumentos:
function sum(x, y) {
  return x + y;
}
const result = sum.apply(null, [3, 8]);
console.log(result); // 11