Je suis tombé sur ce joli raccourci pour convertir une liste de noeuds DOM en un tableau standard, mais je dois admettre que je ne comprends pas tout à fait comment cela fonctionne:
[].slice.call(document.querySelectorAll('a'), 0)
Donc, cela commence par un tableau vide []
, Puis slice
est utilisé pour convertir le résultat de call
en un nouveau tableau, ouais?
Le bit que je ne comprends pas, c'est le call
. Comment cela convertit-il document.querySelectorAll('a')
d'un NodeList en un tableau normal?
Ce qui se passe ici, c'est que vous appelez slice()
comme s'il s'agissait d'une fonction de NodeList
à l'aide de call()
. Dans ce cas, slice()
crée un tableau vide, puis parcourt l'objet sur lequel il est exécuté (à l'origine, un tableau, maintenant un NodeList
) et continue d'ajouter les éléments de cet objet au tableau vide qu'il a créé, qui est finalement retourné. Voici un article sur ceci .
EDIT:
Donc, il commence par un tableau vide [], puis slice est utilisé pour convertir le résultat de l'appel en un nouveau tableau, oui?
Ce n'est pas juste. [].slice
Renvoie un objet fonction. Un objet fonction a une fonction call()
qui appelle la fonction affectant le premier paramètre de la fonction call()
à this
; en d'autres termes, faire croire à la fonction qu'elle est appelée à partir du paramètre (le NodeList
renvoyé par document.querySelectorAll('a')
) plutôt que d'un tableau.
En javascript, les méthodes d'un objet peuvent être liées à un autre objet au moment de l'exécution. En bref, javascript permet à un objet "d'emprunter" la méthode d'un autre objet:
object1 = {
name:'frank',
greet:function(){
alert('hello '+this.name)
}
};
object2 = {
name:'andy'
};
// Note that object2 has no greet method.
// But we may "borrow" from object1:
object1.greet.call(object2); // will show an alert with 'hello andy'
Les méthodes call
et apply
d'objets de fonction (les fonctions en javascript sont également des objets) vous permettent de le faire. Donc, dans votre code, vous pouvez dire que la liste de noeuds emprunte la méthode slice d'un tableau. Qu'est-ce que la conversion est le fait que slice retourne un autre tableau comme résultat?.
Il récupère la fonction slice
d'un Array
. Il appelle ensuite cette fonction, mais en utilisant le résultat de document.querySelectorAll
comme objet this
au lieu d’un tableau.
C'est une technique pour convertir des objets de type tableau en de véritables tableaux.
Certains de ces objets incluent:
arguments
dans les fonctionsCela sert à de nombreuses fins, par exemple les objets sont passés par référence alors que les tableaux sont passés par valeur.
Notez également le premier argument 0
_ peut être omis, explication détaillée ici .
Et dans un souci de complétude, il y a aussi jQuery.makeArray () .
Comment cela convertit-il
document.querySelectorAll('a')
d'unNodeList
en un tableau normal?
C'est le code que nous avons,
[].slice.call(document.querySelectorAll('a'), 0)
Permet de le démonter en premier,
[] // Array object
.slice // Accessing the function 'slice' present in the prototype of Array
.call // Accessing the function 'call' present in the prototype of function object(slice)
(document.querySelectorAll('a'),0)
// 'call' can have arguments like, (thisArg, arg1,arg2...n).
// So here we are passing the 'thisArg' as an array like object,
// that is a 'nodeList'. It will be served as 'this' object inside of slice function.
// And finally setting 'start' argument of slice as '0' and leaving the 'end'
// argument as 'undefined'
Étape 1: exécution de la fonction call
call
, à l'exception de thisArg
, le reste des arguments sera ajouté à une liste d'arguments.slice
sera invoquée en liant sa valeur this
comme thisArg
(un tableau semblable à un objet provient de document.querySelector
) et avec la liste des arguments. i.e] argument start
qui contient 0
Étape: 2 Exécution de la fonction slice
invoquée à l'intérieur de call
start
sera affecté à une variable s
comme 0
end
est undefined
, this.length
sera stocké dans e
a
Après avoir effectué les réglages ci-dessus, l'itération suivante sera effectuée
while(s < e) {
a.Push(this[s]);
s++;
}
a
sera retourné comme résultat.P.S Pour mieux comprendre notre scénario, certaines étapes nécessaires à notre contexte ont été ignorées dans l'algorithme d'origine call et slice .
[].slice.call(document.querySelectorAll('.slide'));
1. The querySelectorAll() method returns all elements in the document that matches a specified selector(s).
2. The call() method calls a function with a given this value and arguments provided individually.
3. The slice() method returns the selected elements in an array, as a new array object.
so this line return the array of [object HTMLDivElement]. Here is the six div with classname "slide" so array length will be 6.
<div class="slideshow">
<div class="slide">
first slider1
</div>
<div class="slide">
first slider2
</div>
<div class="slide">
first slider3
</div>
<div class="slide">
first slider4
</div>
<div class="slide">
first slider5
</div>
<div class="slide">
first slider6
</div>
</div>
<script type="text/javascript">
var arraylist = [].slice.call(document.querySelectorAll('.slide'));
alert(arraylist);
</script>
Depuis ES6: Créez simplement un tableau avec Array.from (element.children) ou Array.from ({length: 5})