Qualcuno può spiegare questo metodo Javascript?
-
20-09-2019 - |
Domanda
Fonte originale: http://twitter.com/tobeytailor/status/8998006366
(x=[].reverse)() === window // true
Ho notato che questo comportamento influisce su tutti i tipi nativi. Che cosa sta succedendo qui?
Soluzione
Questo è a che fare con la this
modo strano opere vincolante in JavaScript.
[].reverse
è il metodo reverse
su un elenco vuoto. Se si voglia chiamare, attraverso uno dei:
[].reverse();
[]['reverse']();
([].reverse)();
allora esegue con this
legato alla lista istanza []
. Ma se si staccarlo:
x= [].reverse;
x();
esegue senza this
vincolante, in modo this
nei punti di funzione al (window
) oggetto globale, in uno dei peggiori, errori di progettazione più fuorvianti di JavaScript.
(x=[].reverse)()
sta facendo il distacco. L'operatore di assegnazione restituisce lo stesso oggetto funzione è stato passato così sembra che sta facendo nulla, ma ha l'effetto collaterale di rompere il caso speciale limitata che provoca JavaScript per legare this
.
Quindi lei sta dicendo:
Array.prototype.reverse.call(window)
reverse
, come molti altri metodi Array.prototype
, è definito da ECMAScript per lavorare su qualsiasi oggetto sequenza simile nativa. Si inverte gli elementi con i tasti numerici-stringa (fino a object.length
) e restituisce l'oggetto. Quindi tornerà l'oggetto che è stato passato a qualsiasi tipo che ha una proprietà length
.
window
ha una proprietà di lunghezza, che corrisponde a window.frames.length
, così chiamata a questo metodo con this
punta a window
funziona e restituire il window
. In teoria può ancora fallire, perché:
-
window
è permesso di essere un “oggetto host” piuttosto che un “oggetto nativo”; in questo caso le garanzie su ciò che è possibile passare a metodi diversi prototipi non si applicano necessariamente; e - se la finestra è in realtà fotogrammi / iframe, sarebbe cercare di invertire il loro ordine, che non avrebbe funzionato perché la raccolta telaio è di sola lettura.
Tuttavia, nei browser attuali primo caso funziona e quest'ultimo non in silenzio, senza un errore, quindi è ancora ottenere il comportamento ===window
e non un'eccezione.