155 votes

Que fait [] .forEach.call () en JavaScript?

Je regardais des extraits de code et j'ai trouvé plusieurs éléments appelant une fonction sur une liste de nœuds avec un forEach appliqué à un tableau vide.

Par exemple, j'ai quelque chose comme:

 [].forEach.call( document.querySelectorAll('a'), function(el) {
   // whatever with the current node
});
 

mais je ne comprends pas comment ça marche. Quelqu'un peut-il m'expliquer le comportement du tableau vide devant le forEach et comment fonctionne le call ?

233voto

Norguard Points 10718

[] est un tableau.
Ce tableau n'est pas utilisé du tout.

Il est mis sur la page, parce que l'utilisation d'un tableau vous donne accès à un tableau de prototypes, comme .forEach.

C'est juste plus rapide que de taper Array.prototype.forEach.call(...);

Ensuite, forEach est une fonction qui prend une fonction comme une entrée...

[1,2,3].forEach(function (num) { console.log(num); });

...et pour chaque élément, en this (où this est semblable au tableau, qu'il a un length vous avez ainsi accès à ses parties, comme this[1]) il va passer trois choses:

  1. l'élément dans le tableau
  2. l'indice de l'élément (troisième élément serait de passer 2)
  3. une référence à la matrice

Enfin, .call est un prototype des fonctions (c'est une fonction qui est appelée à d'autres fonctions).
.call va prendre son premier argument et remplacez - this à l'intérieur de la fonction régulière avec tout ce que vous avez passés call, comme le premier argument (undefined ou null utilisera window dans le quotidien de la JS, ou seront celles que vous avez passé, si dans le "strict-mode"). Le reste des arguments sera passé à la fonction d'origine.

[1, 2, 3].forEach.call(["a", "b", "c"], function (item, i, arr) {
    console.log(i + ": " + item);
});
// 0: "a"
// 1: "b"
// 2: "c"

Par conséquent, vous êtes en train de créer un moyen rapide pour appeler l' forEach de la fonction, et vous êtes évolution this à partir du tableau vide à une liste de tous les <a> tags, et pour chaque <a> dans l'ordre, vous êtes à l'appel de la fonction.

60voto

James Allardice Points 81162

L' querySelectorAll méthode retourne un NodeList, ce qui est similaire à un tableau, mais ce n'est pas tout à fait un tableau. Par conséquent, il n'a pas un forEach méthode (tableau d'objets héritent via Array.prototype).

Depuis un NodeList est similaire à un tableau, les méthodes de tableau seront effectivement faire le travail, donc en utilisant [].forEach.call vous êtes en invoquant l' Array.prototype.forEach méthode dans le contexte de l' NodeList, comme si vous aviez été en mesure de le faire simplement yourNodeList.forEach(/*...*/).

Notez que le tableau vide littérale est juste un raccourci vers la version élargie, qui vous aurez probablement voir très souvent, trop:

Array.prototype.forEach.call(/*...*/);

21voto

Michael Geary Points 10391

Les autres réponses ont très bien expliqué ce code, je vais donc ajouter une suggestion.

Ceci est un bon exemple de code qui devrait être refactoré pour plus de simplicité et de clarté. Au lieu d'utiliser [].forEach.call() ou Array.prototype.forEach.call() chaque fois que vous faites cela, créez-en une fonction simple:

 function forEach( list, callback ) {
    Array.prototype.forEach.call( list, callback );
}
 

Vous pouvez maintenant appeler cette fonction à la place du code plus compliqué et obscur:

 forEach( document.querySelectorAll('a'), function( el ) {
   // whatever with the current node
});
 

6voto

Arun P Johny Points 151748

Il peut être mieux écrit en utilisant

 Array.prototype.forEach.call( document.querySelectorAll('a'), function(el) {

});
 

Ce qui est fait est document.querySelectorAll('a') renvoie un objet similaire à un tableau, mais il n'hérite pas du type Array . Nous appelons donc la méthode forEach partir de l'objet Array.prototype avec le contexte comme valeur renvoyée par document.querySelectorAll('a')

2voto

Ted Hopp Points 122617

Un tableau vide a une propriété forEach de son prototype, qui est une Fonction de l'objet. (Le tableau vide est juste un moyen facile d'obtenir une référence à l' forEach fonction que tous Array des objets ont.) La fonction des objets, à leur tour, ont un call de la propriété qui est également une fonction. Lorsque vous appelez une Fonction call de la fonction, il exécute la fonction avec les arguments donnés. Le premier argument devient this dans la fonction appelée.

Vous pouvez trouver de la documentation pour l' call fonction ici. Documentation pour l' forEach est ici.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X