Szybkie tło: W JavaScript funkcja konstruktora dla każdego typu obiektu ma prototype
właściwość. prototype
Odnosi się do obiektu, co wykonane zastosowania obiektu jako Następnym krokiem w łańcuchu prototypu. Jeśli chcesz, aby jeden typ był nieodłączny od innego typu, możesz ustawić prototype
typ podrzędny na nową instancję typu nadrzędnego.
Na przykład:
var Parent = function() { /* constructor business */ }
Parent.prototype.parentProp = "some parent property";
var Child = function() { /* constructor business */ }
Child.prototype = /*** !! Some prototype object goes here !! ***/
Moje pytanie dotyczy tego, jaki kod powinien znaleźć się w miejscu „ Some prototype object goes here
” w powyższym kodzie. Moim pierwszym instynktem jest zbudowanie instancji nadrzędnej (tj. new Parent()
), Ale w komentarzu do odpowiedzi na pytanie Czy to bezpieczny sposób kopiowania prototypu jednego obiektu na inny? , jeden użytkownik pisze:
Nie, nie używaj
new bar()
dla obiektu prototypowego!
(... co jest opinią, którą widziałem w wielu SO odpowiedziach i komentarzach, ale jest to jedyny przykład, jaki mam w tej chwili pod ręką.)
Inną opcją jest użycie Object.create(Parent.prototype)
jako Child.prototype
. O ile mi wiadomo, tworzy to również nową Parent
instancję, ale nie uruchamia Parent
konstruktora.
Czy ktoś może wyjaśnić, dlaczego należy unikać uruchamiania funkcji konstruktora podczas generowania obiektu prototypowego z typu nadrzędnego? Czy pojawia się jakiś istotny problem techniczny (być może z wieloma poziomami dziedziczenia)? A może taki wzorzec jest niewłaściwym użyciem konstruktorów, które kolidują z pewnymi najlepszymi praktykami prototypowymi (np. Uruchamianie konstruktora podczas tworzenia prototypu narusza pewne rozdzielenie obaw)?
źródło
Object.create
jest zaimplementowane.Object.create
nie działa w IE8” - co jest po prostu bezużytecznym komentarzem, gdy można go zaimplementować w tym przypadku użycia w 2 sekundy w dowolnej przeglądarce.Teraz, gdy moje rozumienie się nieco poszerzyło, chciałbym skorzystać z odpowiedzi Esailii na konkretnym przykładzie:
Jednym szczególnym problemem jest to, że konstruktor może ustawiać właściwości specyficzne dla instancji. Zatem jeśli użyjesz utworzonego obiektu prototypowego
new
, wszystkie twoje instancje potomne mogłyby współdzielić jedną właściwość określoną przez konstruktora z prototypu.Załóżmy na przykład, że
Parent
każda instancja ma unikalnąid
właściwość ustawioną jako czas budowy:Spowoduje to, że wszystkie
Child
instancje będą dzielić pojedyncząid
właściwość prototypową odziedziczoną po jednym i jedynymnew Parent()
obiekcie używanym jakoChild.prototype
.Lepszym podejściem w tym przypadku jest użycie
Object.create
i bezpośrednie wywołanie konstruktora nadrzędnego (w razie potrzeby) wewnątrz konstruktora podrzędnego:źródło