Compreendendo a diferença entre chamar e aplicar em JavaScript

JavaScript

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

Em JavaScript, as funções podem ser invocadas de várias maneiras, e dois métodos comumente usados ​​são `call` e `apply`. Esses métodos permitem controlar o contexto (valor `this`) no qual a função é executada. Compreender a diferença entre `call` e `apply` é crucial para escrever código JavaScript eficiente e eficaz.

Este artigo explora as distinções entre `Function.prototype.call()` e `Function.prototype.apply()` ao invocar uma função. Examinaremos sua sintaxe, casos de uso e possíveis diferenças de desempenho. Ao final deste artigo, você terá uma compreensão clara de quando usar `call` em vez de `apply` e vice-versa.

Comando Descrição
Function.prototype.call() Chama uma função com um determinado valor this e argumentos fornecidos individualmente.
Function.prototype.apply() Chama uma função com um determinado valor this e argumentos fornecidos como uma matriz.
this Refere-se ao objeto a partir do qual a função foi chamada, permitindo a atribuição dinâmica de contexto.
console.log() Imprime mensagens ou variáveis ​​no console para fins de depuração.
res.writeHead() Define o código de status HTTP e os cabeçalhos de resposta em um servidor Node.js.
res.end() Finaliza o processo de resposta em um servidor Node.js, sinalizando que todos os dados foram enviados.
http.createServer() Cria uma instância de servidor HTTP em Node.js, ouvindo solicitações recebidas.
listen() Inicia o servidor HTTP, permitindo que ele escute em uma porta especificada.

Compreendendo o uso de call e apply em JavaScript

Os scripts fornecidos ilustram as diferenças entre usar e em JavaScript. Ambos os métodos são usados ​​para invocar funções com um valor especificado contexto. No primeiro exemplo, o call() método é usado para invocar o método em objetos diferentes ( e ), passando as propriedades de cada objeto como argumentos individuais. Este método permite uma sintaxe concisa quando o número de argumentos é conhecido e fixo. O segundo exemplo demonstra o uso do apply() método, que é semelhante ao mas recebe uma série de argumentos em vez de argumentos individuais. Essa flexibilidade é particularmente útil quando o número de argumentos é variável ou vem de uma fonte de array.

No exemplo de back-end do Node.js, o método é usado em um servidor HTTP criado com . Este exemplo destaca como o o contexto pode ser manipulado em JavaScript do lado do servidor para responder dinamicamente às solicitações HTTP. O servidor responde com uma saudação, demonstrando como o call() método pode mudar o contexto do função. Por fim, o exemplo combinado de front-end e back-end mostra como ambos e pode ser usado em uma função mais dinâmica. Usando call() com argumentos individuais e com uma série de argumentos, o script gera dinamicamente detalhes do usuário, ilustrando as aplicações práticas desses métodos no desenvolvimento JavaScript do lado do cliente e do lado do servidor.

Utilizando métodos call e apply em JavaScript para invocação de função

Script de front-end JavaScript

// Example 1: Using Function.prototype.call()
const person = {
    fullName: function() {
        return this.firstName + " " + this.lastName;
    }
};
const person1 = {
    firstName: "John",
    lastName: "Doe"
};
const person2 = {
    firstName: "Jane",
    lastName: "Smith"
};
// Call the fullName method on person1 and person2
console.log(person.fullName.call(person1)); // Output: John Doe
console.log(person.fullName.call(person2)); // Output: Jane Smith

Aplicando Function.prototype.apply() para passagem flexível de argumentos

Script de front-end JavaScript

// Example 2: Using Function.prototype.apply()
const person = {
    fullName: function(city, country) {
        return this.firstName + " " + this.lastName + ", " + city + ", " + country;
    }
};
const person1 = {
    firstName: "John",
    lastName: "Doe"
};
const person2 = {
    firstName: "Jane",
    lastName: "Smith"
};
// Apply the fullName method with arguments on person1 and person2
console.log(person.fullName.apply(person1, ["New York", "USA"])); // Output: John Doe, New York, USA
console.log(person.fullName.apply(person2, ["London", "UK"])); // Output: Jane Smith, London, UK

Exemplo de back-end do Node.js usando call e apply

Script de back-end JavaScript com Node.js

// Load the required modules
const http = require('http');
// Create a server object
http.createServer((req, res) => {
    res.writeHead(200, {'Content-Type': 'text/plain'});
    // Example using call()
    function greet() {
        return 'Hello ' + this.name;
    }
    const user = { name: 'Alice' };
    res.write(greet.call(user)); // Output: Hello Alice
    res.end();
}).listen(3000);
console.log('Server running at http://localhost:3000/');

Combinando call e apply com uma função dinâmica

Script de pilha completa JavaScript

// Define a function to display user details
function displayDetails(age, profession) {
    return this.name + " is " + age + " years old and works as a " + profession + ".";
}
// User objects
const user1 = { name: 'Bob' };
const user2 = { name: 'Alice' };
// Use call to invoke displayDetails
console.log(displayDetails.call(user1, 30, 'Engineer')); // Output: Bob is 30 years old and works as a Engineer.
// Use apply to invoke displayDetails
console.log(displayDetails.apply(user2, [28, 'Doctor'])); // Output: Alice is 28 years old and works as a Doctor.

Explorando a manipulação de contexto em JavaScript

Além do uso básico de e , esses métodos podem ser combinados com outros recursos JavaScript para criar um código mais complexo e poderoso. Por exemplo, eles são frequentemente usados ​​em conjunto com , que retorna uma nova função com um valor especificado this valor. Diferente e , que invoca imediatamente a função, pode ser usado para criar uma função vinculada que pode ser chamada posteriormente com um contexto consistente. Isto é particularmente útil no tratamento de eventos, onde você pode querer garantir que uma função retenha o contexto de um objeto específico mesmo quando for executada em ambientes diferentes.

Outro caso de uso avançado envolve o empréstimo de métodos de um objeto para uso em outro. Isto pode ser conseguido usando ou para vincular temporariamente um método a um objeto diferente. Por exemplo, métodos de array como ou push() pode ser emprestado e aplicado a objetos semelhantes a array, como o objeto de argumentos em funções. Esta técnica permite maior flexibilidade e reutilização de código, pois permite que métodos sejam compartilhados entre diferentes objetos sem duplicação.

  1. Qual é a principal diferença entre e ?
  2. A principal diferença é que aceita uma lista de argumentos, enquanto aceita uma série de argumentos.
  3. Quando você deve usar sobre ?
  4. Você deveria usar quando você tem uma matriz de argumentos ou precisa passar um número variável de argumentos para uma função.
  5. Existem diferenças de desempenho entre e ?
  6. Geralmente, não há diferenças significativas de desempenho entre e . Quaisquer diferenças são geralmente insignificantes.
  7. Pode ser usado com métodos matemáticos?
  8. Sim, pode ser usado para passar uma matriz de números para métodos matemáticos como ou .
  9. O que é ?
  10. cria uma nova função que, quando chamada, tem seu palavra-chave definida como o valor fornecido, com uma determinada sequência de argumentos precedendo qualquer fornecido quando a nova função é chamada.
  11. Como pode ser usado para emprestar métodos?
  12. Você pode usar emprestar métodos de um objeto e usá-los em outro objeto, permitindo a reutilização de métodos sem copiar a função.
  13. É possível usar ou com construtores?
  14. Não, os construtores não podem ser chamados diretamente com ou . Em vez disso, você pode usar para padrões de herança.
  15. O que são objetos do tipo array e como e trabalhar com eles?
  16. Objetos semelhantes a array são objetos que possuem uma propriedade de comprimento e elementos indexados. e pode ser usado para manipular esses objetos como se fossem arrays.

Em JavaScript, e são essenciais para controlar o contexto dentro das funções. call() permite que argumentos individuais sejam passados, tornando-o adequado para argumentos conhecidos e fixos. Em contraste, aceita uma série de argumentos, fornecendo flexibilidade para listas de argumentos variáveis. Ambos os métodos melhoram a capacidade de reutilização do código e a invocação dinâmica de funções, seja no desenvolvimento front-end ou em ambientes Node.js. Compreender quando e como usar esses métodos de forma eficaz é crucial para escrever código JavaScript limpo e eficiente.