Je suis tombé sur ce raccourci soigné pour convertir un DOM NodeList en un tableau régulier, mais je dois admettre que je ne comprends pas complètement comment cela fonctionne:
[].slice.call(document.querySelectorAll('a'), 0)
Cela commence donc par un tableau vide []
, puisslice
est utilisé pour convertir le résultat de call
dans un nouveau tableau, oui?
Ce que je ne comprends pas, c'est le call
. Comment cela se transforme-t-ildocument.querySelectorAll('a')
d'un NodeList en un tableau normal?
javascript
arrays
call
slice
Yansky
la source
la source
Array.prototype.slice.call(document.querySelectorAll('a'));
est une bonne façon d'écrire le morceau de code que vous avez écrit.Array.from
. Par exemple, cela ferait la même chose: Array.from (document.querySelectorAll ('a'));Réponses:
Ce qui se passe ici, c'est que vous appelez
slice()
comme si c'était une fonction de l'NodeList
utilisationcall()
. Dansslice()
ce cas, il s'agit de créer un tableau vide, puis de parcourir l'item surNodeList
lequel il s'exécute (à l'origine un tableau, maintenant a ) et de continuer à ajouter les éléments de cet objet au tableau vide qu'il a créé, qui est finalement renvoyé. Voici un article à ce sujet .ÉDITER:
Ce n'est pas juste.
[].slice
renvoie un objet fonction. Un objet fonction a une fonctioncall()
qui appelle la fonction affectant le premier paramètre ducall()
àthis
; en d'autres termes, faire penser à la fonction qu'elle est appelée à partir du paramètre (leNodeList
retourné pardocument.querySelectorAll('a')
) plutôt qu'à partir d'un tableau.la source
Array.prototype.slice.call(...)
, il instancie en fait un objet tableau ([]
) uniquement pour accéder à sa méthode de tranche de prototype. C'est une instanciation gaspillée. Dire à laArray.prototype.slice.call(...)
place est plus propre, bien que vous ajoutiez plusieurs caractères à votre JS si vous comptez ...NodeList
s[]
est plus fiable car ilArray
pourrait être remplacé par autre chose. Si vous devez réutiliserArray#slice
, c'est une bonne idée de le mettre en cache.var array = []; var push = array.push; var slice = array.slice; var splice = array.splice;
-il pour le problème de sécurité mentionné par @MathiasBynens?En JavaScript, les méthodes d'un objet peuvent être liées à un autre objet lors de l'exécution. En bref, javascript permet à un objet "d'emprunter" la méthode d'un autre objet:
Les méthodes
call
et lesapply
objets fonction (en JavaScript, les fonctions sont également des objets) vous permettent de le faire. Ainsi, dans votre code, vous pourriez dire que la NodeList emprunte la méthode de tranche d'un tableau..slice()
renvoie un autre tableau comme résultat, qui deviendra le tableau "converti" que vous pourrez ensuite utiliser.la source
call
fonctionArray.prototype
alias[].prototype
vous.Il récupère la
slice
fonction d'unArray
. Il appelle ensuite cette fonction, mais en utilisant le résultat dedocument.querySelectorAll
commethis
objet au lieu d'un tableau réel.la source
C'est une technique pour convertir des objets de type tableau en tableaux réels.
Certains de ces objets incluent:
arguments
dans les fonctionsCela sert à de nombreuses fins, par exemple les objets sont passés par référence tandis que les tableaux sont passés par valeur.
Notez également que le premier argument
0
peut être omis, explication approfondie ici .Et pour être complet, il y a aussi jQuery.makeArray () .
la source
Ceci est le code que nous avons,
Permet de le démonter en premier,
Étape: 1 Exécution de la
call
fonctioncall
, à part lethisArg
, le reste des arguments sera ajouté à une liste d'arguments.slice
sera invoquée en liant sathis
valeur en tant quethisArg
(comme un objet de type tableau provenaitdocument.querySelector
) et avec la liste d'arguments. ie] argumentstart
qui contient0
Étape: 2 Exécution de la
slice
fonction invoquée à l'intérieur decall
start
sera affecté à une variables
comme0
end
estundefined
,this.length
seront stockés danse
a
Après avoir effectué les réglages ci-dessus, l'itération suivante se produira
a
sera retourné comme résultat.PS Pour une meilleure compréhension de notre scénario, certaines étapes nécessaires à notre contexte ont été ignorées de l'algorithme original d' appel et de tranche .
la source
la source
Depuis ES6: créez simplement un tableau avec Array.from (element.children) ou Array.from ({length: 5})
la source