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, e 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 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 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, torna-se extremamente útil. Por outro lado, 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 , otimizando seu código para legibilidade e desempenho.

  1. Qual é a principal diferença entre e ?
  2. aceita argumentos individualmente, enquanto aceita argumentos como uma matriz.
  3. Pode e 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 sobre ?
  6. Usar quando você tem uma matriz de argumentos ou um número variável de argumentos.
  7. Existe alguma diferença de desempenho entre e ?
  8. As diferenças de desempenho são insignificantes na maioria dos casos, mas pode ser um pouco mais rápido com um número fixo de argumentos.
  9. Como e lidar com o contexto?
  10. Ambos os métodos definem explicitamente o contexto para a invocação da função.
  11. Eu posso usar e 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 e ?
  14. Eles são úteis para empréstimo de métodos e manipulação de funções variadas.
  15. Como é que melhorar a legibilidade do código?
  16. torna a invocação da função mais clara quando o número de argumentos é conhecido e fixo.
  17. Pode lidar com um número desconhecido de argumentos?
  18. Sim, é 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 e métodos são ferramentas poderosas em JavaScript para invocar funções com um determinado 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, 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.