2013-12-11 10 views
7

Pytanie na prototype: Dlaczego niektóre metody Array mają .prototype, a inne nie?Dlaczego niektóre metody mają .prototype, a inne nie?

JavaScript Array method names screenshot

W documentation stany "Array.prototype reprezentuje prototyp konstruktora Array".

Próbuję pogodzić to oświadczenie ze zrozumieniem, że prototype jest właściwością odnoszącą się do typu nadrzędnego, ponieważ w ten sposób osiąga się dziedziczenie.

Jeśli to drugie jest prawdą, to co jest typem dominującym Array który „posiada” metody jak map() i indexOf()?

Moje główne pytanie to pytanie z pierwszej linii.

+0

Wszystkie funkcje mają właściwość '.prototype'. – Bergi

+1

@Bergi o tym wiesz;)? (podpowiedź '.bind' i funkcje zdefiniowane przez środowisko hosta) –

+2

@BenjaminGruenbaum: Ups, masz rację. Tylko natywne funkcje * konstruktora * i wszelkie obiekty funkcji utworzone przez użytkownika mają właściwość '.prototype'. Dzięki za heads-up! – Bergi

Odpowiedz

5

Próbuję pogodzić to stwierdzenie ze zrozumieniem, że prototyp jest nieruchomość odnoszące się do rodzaju macierzystego, ponieważ jest to w jaki sposób dziedziczenia został osiągnięty.

Nie. Prototypowa relacja do innego obiektu (z którego właściwości są dziedziczone) jest wykonywana za pomocą niewidocznego łącza, czasami oznaczanego jako [[prototype]].

Faktyczna, istniejąca właściwość .prototype w funkcji konstruktora jest obiektem, z którego wszystkie wystąpienia skonstruowane przez tę funkcję będą dziedziczyć.

Więc prototyp (dziedziczenie) łańcuch obiektu Array wygląda następująco:

       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] 

Dlaczego niektóre metody mają .prototype a inne nie?

Funkcje dostępne w .prototype będą dziedziczone przez wszystkie instancje, można je wywołać bezpośrednio na nich, jeśli są ich metodą.

Funkcje umieszczane bezpośrednio na funkcji konstruktora, takie jak Array.isArray lub Array.of, nie są związane z instancją i "statyczne". Nazywasz je głównie nie-tablicami jako argumentami.

5

Metody, których nie ma na prototypie, są podobne do metod "klasowych" w niektórych innych językach (rodzaj-z; podobieństwo jest powierzchowne). Metody na prototypie można wywoływać z kontekstu dowolnej instancji tablicy; metody bezpośrednio na konstruktorze nie są.

Właściwość "length" jest właściwością każdej instancji tablicy; istnieje również własność "length" w funkcji konstruktora, ale jej znaczenie jest zupełnie inne: — informuje, ile parametrów formalnych znajduje się w funkcji (funkcja Array).

"Typ macierzysty" Array, w zakresie, w jakim takie znaczenie ma sens w JavaScript, to "Obiekt", ale nie ma to nic wspólnego z metodami z prototypu Array.

+0

Chciałbym to powiedzieć za poprawność, ale niepokoi mnie analogia metod "klasowych". Rozważ rozszerzanie tego, co się dzieje. Głównym problemem jest to, że metody znajdujące się na prototypie są dostępne dla każdej tablicy i zwykle mają dynamiczne 'this. –

+0

@BenjaminGruenbaum możesz mi pomóc i dać mi znać, co cię trapi? To znaczy, to też mnie niepokoi, ale jestem ciekawa, co cię tu szczególnie martwi. – Pointy

+0

@BenjaminGruenbaum No cóż, właśnie dodałem kolejne zdanie, przypadkowo. – Pointy

4

The Array.prototype.* metod może być wywoływana przypadkach tablicy, i wydają się być „metoda” w tych przypadkach, podczas gdy metody Array.* nie (a przynajmniej nie bezpośrednio), a zamiast tego mogą być wywoływane z samego obiektu Array.

Na przykład:

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

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

Cóż .. można je wywoływać w instancjach tablicy (pośrednio na przykład) - wszystko można nazwać na wszystko. Byłoby to po prostu bezsensowne, ponieważ nie używają wartości "this". –

+0

@BenjaminGruenbaum Masz rację, aktualizacja. –

Powiązane problemy