Compreendendo a diferença entre `call` e `apply` em JavaScript

Compreendendo a diferença entre `call` e `apply` em JavaScript
JavaScript

Métodos de invocação de função em JavaScript

JavaScript oferece várias maneiras de invocar funções, duas das quais são `Function.prototype.call()` e `Function.prototype.apply()`. Ambos os métodos servem para chamar funções com um valor e argumentos `this` especificados, mas diferem na forma como esses argumentos são passados.

Este artigo tem como objetivo explorar as diferenças entre `call` e `apply`, suas implicações de desempenho e cenários onde um pode ser preferido ao outro. No final, você terá uma compreensão mais clara de quando usar `call` ou `apply` em seu código JavaScript.

Explorando as diferenças entre `call` e `apply` em JavaScript

Exemplo de front-end JavaScript

// Example of Function.prototype.call()
const person = {
  fullName: function() {
    return this.firstName + " " + this.lastName;
  }
};

const person1 = {
  firstName: "John",
  lastName: "Doe"
};

console.log(person.fullName.call(person1)); // John Doe

Compreendendo o desempenho de `call` vs `apply` em JavaScript

Exemplo de front-end JavaScript

// Example of Function.prototype.apply()
const person = {
  fullName: function(city, country) {
    return this.firstName + " " + this.lastName + ", " + city + ", " + country;
  }
};

const person2 = {
  firstName: "Jane",
  lastName: "Doe"
};

console.log(person.fullName.apply(person2, ["Oslo", "Norway"])); // Jane Doe, Oslo, Norway

Comparando `call` e `apply` para invocação de função em JavaScript

Exemplo de back-end do Node.js.

const person = {
  fullName: function(city, country) {
    return this.firstName + " " + this.lastName + ", " + city + ", " + country;
  }
};

const person3 = {
  firstName: "Alice",
  lastName: "Smith"
};

function printName(method) {
  if (method === 'call') {
    console.log(person.fullName.call(person3, 'Paris', 'France'));
  } else if (method === 'apply') {
    console.log(person.fullName.apply(person3, ['Paris', 'France']));
  }
}

printName('call');  // Alice Smith, Paris, France
printName('apply'); // Alice Smith, Paris, France

Escolhendo entre `call` e `apply` no desenvolvimento JavaScript

Análise de desempenho de JavaScript

const iterations = 1000000;
const person = {
  fullName: function(city, country) {
    return this.firstName + " " + this.lastName + ", " + city + ", " + country;
  }
};
const person4 = {
  firstName: "Bob",
  lastName: "Brown"
};

console.time('call');
for (let i = 0; i < iterations; i++) {
  person.fullName.call(person4, 'Berlin', 'Germany');
}
console.timeEnd('call');

console.time('apply');
for (let i = 0; i < iterations; i++) {
  person.fullName.apply(person4, ['Berlin', 'Germany']);
}
console.timeEnd('apply');

Visão mais aprofundada sobre como chamar e aplicar métodos em JavaScript

Além de seu uso básico, Function.prototype.call() e Function.prototype.apply() tem vários casos de uso avançados que podem aprimorar sua programação JavaScript. Um desses casos de uso é o empréstimo de métodos, onde métodos de um objeto são emprestados por outro. Isto é particularmente útil quando você tem um objeto que precisa usar um método de outro objeto sem herança. Usando call() e apply(), você pode emprestar métodos temporariamente e executá-los no contexto de objetos diferentes, aumentando assim a capacidade de reutilização do código e reduzindo a redundância.

Outro aspecto importante a considerar é o uso de apply() para funções variáveis ​​— funções que aceitam um número variável de argumentos. Quando você tem um array de argumentos e precisa passá-los para uma função que não aceita um array, apply() torna-se extremamente útil. Por outro lado, call() pode ser útil em cenários onde o desempenho é crítico e o número de argumentos é conhecido e fixo. Ao compreender essas nuances, os desenvolvedores podem tomar decisões mais informadas sobre quando usar call() contra apply(), otimizando seu código para legibilidade e desempenho.

Perguntas frequentes sobre ligar e inscrever-se em JavaScript

  1. Qual é a principal diferença entre call() e apply()?
  2. call() aceita argumentos individualmente, enquanto apply() aceita argumentos como uma matriz.
  3. Pode call() e apply() ser usado de forma intercambiável?
  4. Sim, podem chegar ao mesmo resultado, mas a escolha depende de como os argumentos estão estruturados.
  5. Quando devo preferir apply() sobre call()?
  6. Usar apply() quando você tem uma matriz de argumentos ou um número variável de argumentos.
  7. Existe alguma diferença de desempenho entre call() e apply()?
  8. As diferenças de desempenho são insignificantes na maioria dos casos, mas call() pode ser um pouco mais rápido com um número fixo de argumentos.
  9. Como call() e apply() lidar com o this contexto?
  10. Ambos os métodos definem explicitamente o this contexto para a invocação da função.
  11. Eu posso usar call() e apply() com funções construtoras?
  12. Não, eles não são adequados para funções construtoras porque não criam novas instâncias.
  13. Quais são alguns casos de uso avançados para call() e apply()?
  14. Eles são úteis para empréstimo de métodos e manipulação de funções variadas.
  15. Como é que call() melhorar a legibilidade do código?
  16. call() torna a invocação da função mais clara quando o número de argumentos é conhecido e fixo.
  17. Pode apply() lidar com um número desconhecido de argumentos?
  18. Sim, apply() é ideal para funções que precisam lidar com um número variável de argumentos.

Considerações finais sobre métodos de invocação de função

Em conclusão, ambos call e apply métodos são ferramentas poderosas em JavaScript para invocar funções com um determinado this valor. A escolha entre eles depende muito de como você deseja passar os argumentos para a função. Enquanto call é melhor ao lidar com um número fixo de argumentos, apply brilha ao lidar com matrizes ou um número desconhecido de argumentos. Compreender essas nuances ajuda a escrever código mais eficiente e legível, levando a melhores práticas de programação JavaScript.