Вопрос

Я наткнулся на этот удобный ярлык для преобразования списка узлов DOM в обычный массив, но должен признать, я не совсем понимаю, как это работает:

[].slice.call(document.querySelectorAll('a'), 0)

Итак, он начинается с пустого массива [], тогда slice используется для преобразования результата call к новому массиву, да?

Единственное, чего я не понимаю, это call.Как это преобразует document.querySelectorAll('a') из списка узлов в обычный массив?

Это было полезно?

Решение

То, что здесь происходит, - это то, что ты называешь slice() как если бы это было функцией NodeList используя call().Что slice() в этом случае создается пустой массив, затем выполняется итерация по объекту, на котором он выполняется (первоначально массив, теперь NodeList) и продолжайте добавлять элементы этого объекта к созданному им пустому массиву, который в конечном итоге возвращается.Вот один статья об этом.

Редактировать:

Итак, он начинается с пустого массива [], затем slice используется для преобразования результата вызова в новый массив, да?

Это неправильно. [].slice возвращает объект функции.Функциональный объект имеет функцию call() который вызывает функцию, присваивающую первый параметр call() Для this;другими словами, заставляя функцию думать, что она вызывается из параметра (the NodeList возвращенный document.querySelectorAll('a')), а не из массива.

Другие советы

В javascript методы объекта могут быть привязаны к другому объекту во время выполнения.Короче говоря, javascript позволяет объекту "заимствовать" метод другого объекта:

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'

В call и apply методы функциональных объектов (в javascript функции также являются объектами) позволяют вам сделать это.Таким образом, в вашем коде вы могли бы сказать, что Nodelist заимствует метод slice массива.Что делает преобразование, так это тот факт, что slice возвращает другой массив в качестве своего результата.

Он извлекает slice функция из Array.Затем он вызывает эту функцию, но используя результат document.querySelectorAll в качестве this объект вместо фактического массива.

Это метод преобразования массивоподобных объектов в реальные массивы.

Некоторые из этих объектов включают:

  • arguments в функциях
  • Список узлов (помните, что их содержимое может измениться после извлечения!таким образом, преобразование их в массив - это способ заморозить их)
  • коллекции jQuery, также известные как объекты jQuery (некоторые документы: API, Тип, Учиться)

Это служит многим целям, например, объекты передаются по ссылке, тогда как массивы передаются по значению.

Также обратите внимание на первый аргумент 0 может быть опущен, подробное объяснение здесь.

И для полноты картины, есть также jQuery.makeArray().

Как это преобразует document.querySelectorAll('a') из a NodeList к обычному массиву?

Это код, который у нас есть,

[].slice.call(document.querySelectorAll('a'), 0)

Давайте сначала разберем его,

  []    // 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'

Шаг:1 Выполнение call функция

  • Внутри call, кроме thisArg, остальные аргументы будут добавлены к списку аргументов.
  • Теперь функция slice будет вызван путем привязки его this значение как thisArg (массивоподобный объект пришел из document.querySelector) и со списком аргументов.т.е.] аргумент start который содержит 0

Шаг:2 Выполнение slice функция, вызываемая внутри call

  • start будет присвоен переменной s как 0
  • с тех пор как end является undefined, this.length будет храниться в e
  • пустой массив будет сохранен в переменной a
  • После выполнения вышеуказанных настроек произойдет следующая итерация

    while(s < e) {
      a.push(this[s]);
      s++;
    }
    
  • заполненный массив a будет возвращен как результат.

P.S Для лучшего понимания нашего сценария некоторые шаги, необходимые для нашего контекста, были проигнорированы из исходного алгоритма позвонить и нарезать.

[].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>

Из ES6:Просто создайте массив с помощью Array.from(элемент.дочерниеэлементы) или Массив.из({длина:5})

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top