Compreendendo a diferença entre chamar e aplicar em JavaScript

Compreendendo a diferença entre chamar e aplicar em JavaScript
Compreendendo a diferença entre chamar e aplicar em 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 Function.prototype.call() e Function.prototype.apply() em JavaScript. Ambos os métodos são usados ​​para invocar funções com um valor especificado this contexto. No primeiro exemplo, o call() método é usado para invocar o fullName método em objetos diferentes (person1 e person2), 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 call() 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 call() método é usado em um servidor HTTP criado com http.createServer(). Este exemplo destaca como o this 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 greet função. Por fim, o exemplo combinado de front-end e back-end mostra como ambos call() e apply() pode ser usado em uma função mais dinâmica. Usando call() com argumentos individuais e apply() 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 call() e apply(), 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 bind(), que retorna uma nova função com um valor especificado this valor. Diferente call() e apply(), que invoca imediatamente a função, bind() 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 call() ou apply() para vincular temporariamente um método a um objeto diferente. Por exemplo, métodos de array como slice() 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.

Perguntas comuns sobre como ligar e se inscrever em JavaScript

  1. Qual é a principal diferença entre call() e apply()?
  2. A principal diferença é que call() aceita uma lista de argumentos, enquanto apply() aceita uma série de argumentos.
  3. Quando você deve usar apply() sobre call()?
  4. Você deveria usar apply() 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 call() e apply()?
  6. Geralmente, não há diferenças significativas de desempenho entre call() e apply(). Quaisquer diferenças são geralmente insignificantes.
  7. Pode apply() ser usado com métodos matemáticos?
  8. Sim, apply() pode ser usado para passar uma matriz de números para métodos matemáticos como Math.max() ou Math.min().
  9. O que é Function.prototype.bind()?
  10. bind() cria uma nova função que, quando chamada, tem seu this 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 call() ser usado para emprestar métodos?
  12. Você pode usar call() 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 call() ou apply() com construtores?
  14. Não, os construtores não podem ser chamados diretamente com call() ou apply(). Em vez disso, você pode usar Object.create() para padrões de herança.
  15. O que são objetos do tipo array e como call() e apply() trabalhar com eles?
  16. Objetos semelhantes a array são objetos que possuem uma propriedade de comprimento e elementos indexados. call() e apply() pode ser usado para manipular esses objetos como se fossem arrays.

Resumindo o uso de call e apply em JavaScript

Em JavaScript, call() e apply() são essenciais para controlar o this contexto dentro das funções. call() permite que argumentos individuais sejam passados, tornando-o adequado para argumentos conhecidos e fixos. Em contraste, apply() 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.