2013-12-11 16 views
7

Domanda su prototype: Perché alcuni metodi di matrice hanno .prototype e altri no?Perché alcuni metodi hanno .prototype e altri no?

JavaScript Array method names screenshot

Le documentation Stati "Array.prototype rappresenta il prototipo della Array costruttore".

Sto cercando di conciliare questa affermazione con la comprensione che prototype è una proprietà che si riferisce al tipo genitore, poiché è così che si ottiene l'ereditarietà.

Se quest'ultimo è vero, qual è il tipo principale di Array chi "possiede" i metodi come map() e indexOf()?

La mia domanda principale è quella sulla prima riga.

+0

Tutte le funzioni hanno una proprietà '.prototype'. – Bergi

+1

@Bergi sei sicuro di questo;)? (suggerimento '.bind' e funzioni definite dall'ambiente host) –

+2

@BenjaminGruenbaum: Oops, hai ragione. Solo le funzioni di costruzione * native * e tutti gli oggetti funzione creati dall'utente hanno una proprietà '.prototype'. Grazie per il testa a testa! – Bergi

risposta

5

Sto cercando di conciliare questa affermazione con la consapevolezza che il prototipo è una proprietà con riferimento al tipo genitore, dal momento che è come si ottiene l'ereditarietà.

No. Il rapporto prototipo ad un altro oggetto (da cui vengono ereditate proprietà) avviene tramite un collegamento invisibile, talvolta indicato come [[prototype]].

La proprietà attuale esistente .prototype su una funzione di costruzione è l'oggetto da cui erediteranno tutte le istanze che sono state costruite da tale funzione.

Quindi il prototipo (eredità) la catena di un oggetto Array assomiglia a questo:

       null 
          ^
           | 
Object.prototype ---> {hasOwnProperty(), …} // all objects inherit these 
          ^
           | 
Array.prototype ----> {map(), indexOf(), …} // all arrays inherit these 
          ^
           | 
         {length, 0, 1, 2, …} // an example array 
         // as if constructed by new Array(5) or [42, 7, 6] 

Perché alcuni metodi hanno .prototype e alcuni non lo fanno?

Le funzioni che sono disponibili sul .prototype verrà ereditata da tutte le istanze, si possono chiamare direttamente su di loro se fossero un metodo di loro.

Le funzioni che si trovano direttamente sulla funzione di costruzione, come Array.isArray o Array.of, non sono correlate all'istanza e "statiche", per così dire. Li chiami principalmente con i non-array come argomenti.

5

I metodi che non sono sul prototipo sono come metodi di "classe" in alcune altre lingue (tipo-di, la somiglianza è superficiale). I metodi sul prototipo sono callable dal contesto di qualsiasi istanza di array; i metodi direttamente sul costruttore non lo sono.

La proprietà "length" è una proprietà di ogni istanza di array; c'è anche una proprietà "length" sulla funzione del costruttore, ma il suo significato è completamente diverso: — indica quanti parametri formali sono presenti nella funzione (la funzione Array).

Il "tipo genitore" di Array, nella misura in cui una cosa del genere ha senso in JavaScript, è "Oggetto", ma questo non ha nulla a che fare con i metodi sul prototipo di Array.

+0

Mi piacerebbe sovvertire questo per essere corretto, ma l'analogia dei metodi di "classe" mi dà fastidio. Per favore considera di espandere ciò che sta accadendo. Il problema principale è che i metodi che sono sul prototipo sono disponibili per ogni array e di solito hanno questo 'dinamico. –

+0

@BenjaminGruenbaum puoi aiutarmi e farmi sapere cosa ti dà fastidio esattamente? Voglio dire, mi disturba anche io, ma sono curioso di sapere cosa ti preoccupa esattamente qui. – Pointy

+0

@BenjaminGruenbaum Ah bene, ho appena aggiunto un'altra frase, per coincidenza. – Pointy

4

I Array.prototype.* metodi possono essere chiamati istanze di matrice, e sembrano essere 'metodo' di quei casi, mentre i metodi non possono Array.* (almeno non direttamente), e invece devono essere chiamate dall'oggetto Array stessa.

Ad esempio:

[].concat([]) // calls Array.prototype.concat 
Array.concat([]) // undefined 

Array.isArray([]) // calls Array.isArray 
[].isArray([]) // undefined 
+1

Bene ... possono essere chiamati su istanze di array (indirettamente per esempio) - tutto può essere chiamato su tutto. Sarebbe semplicemente inutile dal momento che non usano il valore 'this'. –

+0

@BenjaminGruenbaum Hai ragione, aggiornato. –

Problemi correlati