Różnica między tablicami.slice i Array ().slice

Idę przez John Resig excellent Advanced JavaScript tutorial i nie bardzo rozumiem, jaka jest różnica między następujących wywołań :( proszę zauważyć, że 'argumenty' jest wbudowany słowo javascript i nie jest dokładnie tablica stąd hacking z tablicy.slice zamiast po prostu wywoływać argumenty.slice)

>>> arguments  
[3, 1, 2, 3]  
>>> Array.slice.call( arguments )  
3,1,2,3 0=3 1=1 2=2 3=3  
>>> Array.slice.call( arguments, 1 )  
[]
>>> Array().slice.call( arguments )  
3,1,2,3 0=3 1=1 2=2 3=3  
>>> Array().slice.call( arguments, 1 )  
1,2,3 0=1 1=2 2=3  
Zasadniczo moje nieporozumienie sprowadza się do różnicy między tablicami.slice i Array ().plaster. Czym dokładnie jest różnica między tymi dwoma i dlaczego nie tablica.plaster.zadzwoń, zachowaj się zgodnie z oczekiwaniami? (co oddaje wszystkie oprócz pierwszego elementu listy argumentów).
Author: juan, 2008-09-23

6 answers

Niezupełnie.

Uważaj, co się dzieje, gdy wywołujesz String./ align = "left" / call ("foo", 1) i String ()./ align = "left" / call ("foo", 2):

>>> String.substring.call("foo", 1)
"1"

>>> String().substring.call("foo", 1)
"oo"

Array.slice nie jest ani, ani poprawnie odwołuje się do funkcji slice dołączonej do prototypu tablicy, ani do funkcji slice dołączonej do instancyjnej instancji tablicy (takiej jak Array () lub []).

Fakt, że tablica.slice jest nawet non-null w ogóle jest niepoprawną implementacją samego obiektu (/function / constructor). Spróbuj uruchomienie równoważnego kodu w IE i dostaniesz błąd, że tablica.slice jest null .

Dlatego Array.slice nie zachowuje się poprawnie (podobnie jak String.substring).

Dowód (poniżej jest coś, czego nie należy się spodziewać na podstawie definicji slice ()...podobnie jak substring () powyżej):

>>> Array.slice.call([1,2], [3,4])
3,4

Teraz, jeśli poprawnie wywołasz slice() na instancyjnym obiekcie lub prototyp tablicy, otrzymasz to, czego oczekujesz:

>>> Array.prototype.slice.call([4,5], 1)
[5]
>>> Array().slice.call([4,5], 1)
[5]

Więcej dowód...

>>> Array.prototype.slice == Array().slice
true
>>> Array.slice == Array().slice
false
 39
Author: kamens,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-23 14:22:51

Tablica jest tylko funkcją, aczkolwiek specjalną (używaną do inicjalizacji tablic). / Align = "left" / slice jest odniesieniem do funkcji slice () w prototypie tablicy. Można ją wywołać tylko na obiekcie array, a nie na samym Konstruktorze (tzn. tablicy). Array wydaje się zachowywać specjalnie, ponieważ Array () zwraca pustą tablicę. Wydaje się, że to nie działa w przypadku nie wbudowanych funkcji konstruktora (tam musisz użyć nowego). Więc

Array().slice.call

Jest tym samym co

[].slice.call
 6
Author: ujh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-23 13:39:18

Jak to jest, aby każde wezwanie do cięcia.call () działa w podanych przykładach, ponieważ parametr context nie jest dostarczany? Czy slice implementuje własną metodę wywołania, tym samym nadpisując metodę wywołania JavaScript? Metody call I apply przyjmują jako pierwszy parametr obiekt określający kontekst (ten) obiektu, który ma zostać zastosowany do wywołania.

 1
Author: Bill,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-11-28 20:22:08

Uważam, że Array jest typem, a Array () jest funkcją konstruktora.

Messing around in FireBug :

>>> Array === Array()
false

>>> Array.constructor
Function()

>>> Array().constructor
Array()
 0
Author: cllpse,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-23 13:51:37

Cóż,

Patrząc na http://www.devguru.com/Technologies/ecmascript/quickref/slice.html

Array ().slice jest funkcją (konstruktorem) w klasie array, nie może być używana jako element danych. Jeśli nie chcesz używać ' ()', musisz wywołać go w tablicy. ie-argumenty.slice (1)

 -1
Author: Brad8118,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-23 13:42:46

Domyślam się, że Array jest prototypem, podczas gdy Array() jest rzeczywistym obiektem array. W zależności od interpretacji JavaScript, bezpośrednie wywołanie prototypowej metody wbudowanego typu obiektu może działać lub nie. Nie wierzę, że spec mówi, że musi działać, tylko, że wywołanie go na instancyjnym obiekcie działa.

 -1
Author: Michael Johnson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-23 13:43:31