Natknąłem się na ten zgrabny skrót do konwersji DOM NodeList w zwykłą tablicę, ale muszę przyznać, że nie do końca rozumiem, jak to działa:
[].slice.call(document.querySelectorAll('a'), 0)
Więc zaczyna się od pustej tablicy []
, a następnie slice
służy do konwersji wyniku call
na nową tablicę, tak?
Nie rozumiem tylko tego call
. Jak to się przekształca document.querySelectorAll('a')
z NodeList do zwykłej tablicy?
javascript
arrays
call
slice
Yansky
źródło
źródło
Array.prototype.slice.call(document.querySelectorAll('a'));
to właściwy sposób na napisanie fragmentu kodu, który napisałeś.Array.from
. Tak więc np. Zrobiłoby to samo: Array.from (document.querySelectorAll ('a'));Odpowiedzi:
To, co się tutaj dzieje, polega na tym, że dzwonisz
slice()
tak, jakby to była funkcjaNodeList
używaniacall()
. Coslice()
robi w tym przypadku jest utworzyć pustą tablicę, następnie iterację obiektu to działa (pierwotnie na tablicy, terazNodeList
) i utrzymać dołączanie elementów tego obiektu do pustej tablicy utworzony, który ostatecznie powrócił. Oto artykuł na ten temat .EDYTOWAĆ:
To nie tak.
[].slice
zwraca obiekt funkcji. Obiekt funkcji ma funkcję,call()
która wywołuje funkcję przypisującą pierwszy parametrcall()
dothis
; innymi słowy, sprawiając, że funkcja myśli, że jest wywoływana z parametru (NodeList
zwróconego przezdocument.querySelectorAll('a')
), a nie z tablicy.źródło
Array.prototype.slice.call(...)
, w rzeczywistości tworzy on obiekt tablicowy ([]
) tylko w celu uzyskania dostępu do jego metody wycinania prototypów. To zmarnowana instancja. MówienieArray.prototype.slice.call(...)
zamiast tego jest czystsze, chociaż dodajesz kilka znaków do JS, jeśli liczysz ...NodeList
s[]
jest bardziej niezawodny, ponieważArray
można go zastąpić czymś innym. Jeśli musisz użyć ponownieArray#slice
, dobrze jest buforować.var array = []; var push = array.push; var slice = array.slice; var splice = array.splice;
Czy robi to w związku z kwestią bezpieczeństwa wspomnianą przez @MathiasBynens?W JavaScript metody obiektu można powiązać z innym obiektem w czasie wykonywania. W skrócie, javascript pozwala obiektowi „pożyczyć” metodę innego obiektu:
Te
call
iapply
metody obiektów funkcyjnych (w JavaScript, funkcje są obiektami, jak również) pozwala to zrobić. Zatem w kodzie można powiedzieć, że NodeList pożycza metodę plasterka tablicy..slice()
zwraca inną tablicę jako wynik, która stanie się „skonwertowaną” tablicą, z której będziesz mógł korzystać.źródło
call
funkcjiArray.prototype
aka[].prototype
siebie.Pobiera
slice
funkcję zArray
. Następnie wywołuje tę funkcję, ale używając wynikudocument.querySelectorAll
jakothis
obiektu zamiast rzeczywistej tablicy.źródło
Jest to technika przekształcania obiektów tablicowych w prawdziwe tablice.
Niektóre z tych obiektów obejmują:
arguments
w funkcjachSłuży to wielu celom, na przykład obiekty są przekazywane przez odniesienie, a tablice są przekazywane przez wartość.
Zauważ też, że pierwszy argument
0
można pominąć, dokładne wyjaśnienie tutaj .Dla zapewnienia kompletności istnieje również jQuery.makeArray () .
źródło
To jest kod, który mamy,
Najpierw go zdemontujmy,
Krok: 1 Wykonanie
call
funkcjicall
, poza tymthisArg
, pozostałe argumenty zostaną dołączone do listy argumentów.slice
zostanie wywołana przez powiązanie jejthis
wartości jakothisArg
(pochodzi z obiektu typu tablicowegodocument.querySelector
) i listy argumentów. ie] argument,start
który zawiera0
Krok: 2 Wywołanie
slice
funkcji wywołanej wewnątrzcall
start
zostanie przypisany do zmiennejs
jako0
end
jestundefined
,this.length
będzie przechowywany we
a
Po wprowadzeniu powyższych ustawień nastąpi następująca iteracja
a
jako wynik zostanie zwrócona wypełniona tablica .PS Aby lepiej zrozumieć nasz scenariusz, niektóre kroki niezbędne dla naszego kontekstu zostały zignorowane z oryginalnego algorytmu call and slice .
źródło
źródło
Z ES6: Po prostu stwórz tablicę za pomocą Array.from (element.children) lub Array.from ({length: 5})
źródło