Объяснение [].slice.call в javascript?
Я наткнулся на этот аккуратный ярлык для преобразования DOM NodeList в обычный массив, но я должен признать, что я не совсем понимаю, как это работает:
[].slice.call(document.querySelectorAll('a'), 0)
Итак, он начинается с пустого массива []
, затем slice
используется для преобразования результата call
в новый массив yeah?
Бит, который я не понимаю, это call
. Как это преобразование document.querySelectorAll('a')
из NodeList в регулярный массив?
Ответы
Ответ 1
Здесь происходит то, что вы вызываете slice()
, как если бы это была функция NodeList
, используя call()
. То, что slice()
делает в этом случае, создает пустой массив, затем выполняет итерацию через объект, на котором он выполняется (изначально массив, теперь NodeList
), и продолжайте добавлять элементы этого объекта в пустой массив, который он создал, в конечном итоге вернулся. Здесь статья об этом.
EDIT:
Итак, он начинается с пустого массива [], а затем срез используется для преобразовать результат вызова в новый массив да?
Это не так. [].slice
возвращает объект функции. Функциональный объект имеет функцию call()
, которая вызывает функцию, назначающую первый параметр от call()
до this
; другими словами, заставляя функцию думать, что она вызывается из параметра (NodeList
, возвращаемого document.querySelectorAll('a')
), а не из массива.
Ответ 2
В 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);
Методы call
и apply
объектов функций (в функциях javascript тоже являются объектами) позволяют это сделать. Таким образом, в вашем коде можно сказать, что Nodelist заимствует метод среза массива. Что такое преобразование, так это то, что срез возвращает другой массив, как результат.
Ответ 3
Он извлекает функцию slice
из Array
. Затем он вызывает эту функцию, но использует результат document.querySelectorAll
как объект this
вместо фактического массива.
Ответ 4
Это метод преобразования объектов, подобных массиву, в реальные массивы.
Некоторые из этих объектов включают в себя:
-
arguments
в функциях
- NodeList (помните, что их содержимое может измениться после извлечения, поэтому преобразование их в массив является способом их замораживания)
- коллекции jQuery, aka объекты jQuery (некоторые doc: API, type, learn)
Это служит для многих целей, например, объекты передаются по ссылке, тогда как массивы передаются по значению.
Также обратите внимание, что первый аргумент 0
может быть опущен, подробное объяснение здесь.
И для полноты также существует jQuery.makeArray().
Ответ 5
Как это преобразование document.querySelectorAll('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
) и с помощью списка аргументов. i.e] аргумент start
, который содержит 0
Шаг: 2 Выполнение функции slice
, вызванной внутри call
PS Для лучшего понимания нашего сценария некоторые шаги, необходимые для нашего контекста, были проигнорированы из исходного алгоритма call и срез.
Ответ 6
[].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>
Ответ 7
Из ES6: просто создайте массив с Array.from(element.children) или Array.from({length: 5})