Ma to związek z dziwnym sposobem wiązania kodu w języku JavaScript.
[].reverse
to metoda reverse
na pustej liście. Jeśli go nie nazywać, za pośrednictwem jednego z:
[].reverse();
[]['reverse']();
([].reverse)();
następnie wykonuje z this
związany instancji listy []
. Ale jeśli odłączyć go:
x= [].reverse;
x();
to wykonuje bez this
-binding, więc this
w punktach funkcji do globalnej (window
) obiektu, w jednym z najgorszych, najbardziej mylących błędów projektowych jest obsługa JavaScript.
(x=[].reverse)()
Wykonuje również odczep. Operator przypisania zwraca ten sam obiekt funkcji, który został przekazany, więc wygląda na to, że nic nie robi, ale ma efekt uboczny zerwania ograniczonego specjalnego przypadku, który powoduje, że JavaScript wiąże się z this
.
Więc mówisz:
Array.prototype.reverse.call(window)
reverse
, podobnie jak wiele innych Array.prototype
metod, jest zdefiniowany przez ECMAScript pracować na dowolnym natywnej sekwencji podobnego przedmiotu. Odwraca elementy za pomocą klawiszy numerycznych (do object.length
) i zwraca obiekt. Zwróci obiekt, który został przekazany dla dowolnego typu, który ma właściwość length
.
window
ma właściwość length, która odpowiada window.frames.length
, więc wywołanie tej metody z this
wskazując na window
zadziała i zwróci window
. Teoretycznie może nadal zawieść, ponieważ:
window
może być "obiektem hosta", a nie "obiektem macierzystym"; w tym przypadku gwarancje dotyczące tego, co można przekazać metodom innych prototypów, niekoniecznie mają zastosowanie; i
- jeśli okno faktycznie ma ramki/ramki, to spróbuje odwrócić ich kolejność, która nie działałaby, ponieważ kolekcja ramek jest tylko do odczytu.
Jednak w obecnych przeglądarek byłego przypadek działa, a drugi nie cicho bez błędu, więc nadal uzyskać zachowanie ===window
a nie wyjątek.
'[] .reverse.call (y) === y' dla wszystkich skalarów' y'. – kennytm
* Zauważyłem, że to zachowanie ... * Jakie zachowanie? – Cheeso