Domanda

Sto esaminando l'eccellente Tutorial javascript avanzato di John Resig e non capisco bene cosa sia la differenza tra le seguenti chiamate: (si noti che 'argomenti' è una parola javascript integrata e non è esattamente un array, quindi l'hacking con Array.slice invece di chiamare argomenti.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  

Fondamentalmente il mio malinteso si riduce alla differenza tra Array.slice e Array (). slice. Qual è esattamente la differenza tra questi due e perché Array.slice.call non si comporta come previsto? (che sta restituendo tutto tranne il primo elemento dell'elenco degli argomenti).

È stato utile?

Soluzione

Non proprio.

Guarda cosa succede quando chiami String.substring.call (" foo " ;, 1) e String (). substring.call (" foo " ;, 2):

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

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

Array.slice non è correttamente riferito alla funzione slice collegata al prototipo di array né alla funzione slice collegata a qualsiasi istanza di array istanziata (come Array () o []).

Il fatto che Array.slice sia addirittura non nullo è un'implementazione errata dell'oggetto stesso (/ funzione / costruttore) stesso. Prova a eseguire il codice equivalente in IE e visualizzerai un errore che Array.slice è null .

Ecco perché Array.slice non si comporta correttamente (né String.substring).

Prova (il seguente è qualcosa che non ci si dovrebbe aspettare in base alla definizione di slice () ... proprio come la sottostringa () sopra):

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

Ora, se chiami correttamente slice () su un oggetto istanziato o il prototipo Array, otterrai ciò che ti aspetti:

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

Altre prove ...

>>> Array.prototype.slice == Array().slice
true
>>> Array.slice == Array().slice
false

Altri suggerimenti

L'array è solo una funzione, sebbene speciale (utilizzata per inizializzare gli array). Array.slice è un riferimento alla funzione slice () nel prototipo di array. Può essere chiamato solo su un oggetto array e non sul costruttore (ovvero array) stesso. L'array sembra comportarsi in modo speciale, tuttavia, poiché Array () restituisce un array vuoto. Questo non sembra funzionare per le funzioni di costruzione non incorporate (lì devi usare nuove). Quindi

Array().slice.call

è uguale a

[].slice.call

Come funziona una chiamata a slice.call () negli esempi forniti poiché non viene fornito un parametro di contesto? Slice implementa il proprio metodo di chiamata, sovrascrivendo così il metodo di chiamata di JavaScript? I metodi call e apply accettano come primo parametro un oggetto per specificare l'oggetto di contesto (questo) da applicare all'invocazione.

Credo che Array sia il tipo e Array () è la funzione di costruzione.

Divertiti a FireBug :

>>> Array === Array()
false

>>> Array.constructor
Function()

>>> Array().constructor
Array()

Bene,

Guardando http://www.devguru.com/Technologies/ecmascript /quickref/slice.html

Array (). slice è una funzione (costruttore) nella classe array, non può essere utilizzata come membro dati. Se non si desidera utilizzare "()", è necessario chiamarlo sull'array. vale a dire - argomenti.slice (1)

La mia ipotesi è che Array sia un prototipo mentre Array () è un vero oggetto array. A seconda dell'interpretazione JavaScript, la chiamata diretta al metodo prototipo di un tipo di oggetto incorporato potrebbe funzionare oppure no. Non credo che le specifiche dicano che deve funzionare, solo che chiamarlo su un oggetto istanziato funziona.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top