web-dev-qa-db-fra.com

Explication de [] .slice.call en javascript?

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?

178
Yansky

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.

144
Max Shawabkeh

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?.

110
slebetman

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.

26
Brian Campbell

C'est une technique pour convertir des objets de type tableau en de véritables tableaux.

Certains de ces objets incluent:

  • arguments dans les fonctions
  • NodeList (rappelez-vous que leur contenu peut changer après avoir été récupéré! Donc les convertir en tableau est un moyen de les figer)
  • collections jQuery, aussi appelées objets jQuery (un peu de doc: API , type , apprendre )

Cela 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 () .

19
Gras Double

Comment cela convertit-il document.querySelectorAll('a') d'un NodeList 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

  • À l'intérieur de call, à l'exception de thisArg, le reste des arguments sera ajouté à une liste d'arguments.
  • Maintenant, la fonction 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
  • puisque end est undefined, this.length sera stocké dans e
  • un tableau vide sera stocké dans une variable 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++;
    }
    
  • le tableau rempli 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 .

12
[].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>
5
Ankit Parmar

Depuis ES6: Créez simplement un tableau avec Array.from (element.children) ou Array.from ({length: 5})

3
Мони