W JavaScript jaka jest różnica między tymi dwoma przykładami:
Warunek wstępny:
function SomeBaseClass(){
}
SomeBaseClass.prototype = {
doThis : function(){
},
doThat : function(){
}
}
Przykład dziedziczenia A przy użyciu Object.create:
function MyClass(){
}
MyClass.prototype = Object.create(SomeBaseClass.prototype);
Przykład dziedziczenia B przy użyciu nowego słowa kluczowego
function MyClass(){
}
MyClass.prototype = new SomeBaseClass();
Oba przykłady wydają się robić to samo. Kiedy wybrałbyś jedną z nich?
Dodatkowe pytanie: Rozważ kod w poniższym linku (wiersz 15), gdzie w prototypie znajduje się odniesienie do własnego konstruktora funkcji. Dlaczego jest to przydatne?
https://github.com/mrdoob/three.js/blob/master/src/loaders/ImageLoader.js
Fragment (jeśli nie chcesz otwierać linku):
THREE.ImageLoader.prototype = {
constructor: THREE.ImageLoader
}
javascript
inheritance
object-create
ChrisRich
źródło
źródło
Object.create
. To pomyłka i należy ją ponownie otworzyć.Odpowiedzi:
W swoim pytaniu wspomniałeś, że
Both examples seem to do the same thing
to wcale nie jest prawda, ponieważTwój pierwszy przykład
W tym przykładzie po prostu dziedziczysz,
SomeBaseClass' prototype
ale co, jeśli maszSomeBaseClass
podobną właściwośća jeśli używasz go jak
obj
Obiekt nie będzie miałpublicProperty
właściwości jak w tym przykładzie .Twój drugi przykład
Wykonuje
constructor
funkcję, tworzy instancjęSomeBaseClass
i dziedziczy całySomeBaseClass
obiekt. Więc jeśli używaszW tym przypadku jego
publicProperty
właściwość jest również dostępna dlaobj
obiektu, jak w tym przykładzie .Ponieważ
Object.create
nie jest dostępny w niektórych starszych przeglądarkach, w takim przypadku możesz użyćPowyższy kod po prostu dodaje
Object.create
funkcję, jeśli nie jest dostępna, więc możesz użyćObject.create
funkcji i myślę, że powyższy kod opisuje, coObject.create
faktycznie robi. Mam nadzieję, że to w jakiś sposób pomoże.źródło
SomeBaseClass
.To prawda w twoim przypadku.
Gdy
SomeBaseClass
ma treść funkcji, zostanie wykonane za pomocąnew
słowa kluczowego. Zwykle nie jest to zamierzone - chcesz tylko skonfigurować łańcuch prototypów. W niektórych przypadkach może to nawet spowodować poważne problemy, ponieważ w rzeczywistości tworzysz instancję obiektu, którego zmienne o zasięgu prywatnym są wspólne dla wszystkichMyClass
instancji, ponieważ dziedziczą one te same uprzywilejowane metody. Można sobie wyobrazić inne skutki uboczne.Więc generalnie powinieneś preferować
Object.create
. Jednak nie jest obsługiwany w niektórych starszych przeglądarkach; z tego powodu widzisz tonew
podejście zbyt często, ponieważ często nie powoduje ono (oczywistej) szkody. Spójrz także na tę odpowiedź .źródło
Różnica staje się oczywista, jeśli używasz
Object.create()
go zgodnie z przeznaczeniem. Właściwie to całkowicie ukrywaprototype
słowo przed twoim kodem, wykona pracę pod maską. UżywającObject.create()
, możemy iść jakA potem możemy z tego rozszerzać / dziedziczyć inne obiekty
Jest to więc inna koncepcja, bardziej „obiektowy” sposób dziedziczenia. Na przykład nie ma „funkcji konstruktora” po wyjęciu z pudełka
Object.create()
. Ale oczywiście możesz po prostu utworzyć i wywołać samodzielnie zdefiniowaną funkcję konstruktora w tych obiektach.Jednym z argumentów za korzystanie
Object.create()
jest to, że może to wyglądać bardziej naturalny do mix / * * dziedziczą od innych przedmiotów, niż przy użyciu JavaScripts domyślny sposób .źródło
Object.create
tak naprawdę nie można zastąpić klasycznego podejścia,new
kiedy potrzebna jest funkcja konstruktoraObject.create
nie wywołuje funkcji, która byłaby konieczna do tworzenia domknięć. OczywiścieObject.create
możesz umieścićinit
metodę na swoich obiektach i wywołać ją natychmiast, a może nawet zwrócithis
, aby uzyskać zwięzłą składnię - ale poczekaj, to jest konstruktor.new
używa „powiązania obiektów”, więc nie ma dużej różnicy. W rzeczywistości są tylko dwie rzeczy:.constructor
jest wywoływana.init
, a ta funkcja nie ma.prototype
właściwości wskazującej z powrotem na twój prototypowy obiekt. Reszta to tylko składnia - i wolęnew X
od niejObject.create(x).init()
.Nie jestem ekspertem w zakresie skryptów Java, ale oto prosty przykład, aby zrozumieć różnicę między „Object.create” a „new”.
krok 1: utwórz funkcję nadrzędną z pewnymi właściwościami i akcjami.
krok 2: utwórz funkcję potomną (PersonSalary), która wykracza poza funkcję Person za pomocą słowa kluczowego New .
krok 3: utwórz drugą funkcję potomną (PersonLeaves), która rozszerza funkcję osoby powyżej za pomocą słowa kluczowego Object.create .
// Teraz sprawdź prototypy obu funkcji potomnych.
obie te funkcje potomne będą łączyły się z prototypem Person (funkcja nadrzędna) i będą miały dostęp do jego metod, ale jeśli utworzysz funkcję potomną za pomocą nowego, zwróci ona zupełnie nowy obiekt ze wszystkimi właściwościami nadrzędnymi, których nie potrzebujemy, a także po utworzeniu jakichkolwiek obiekt lub funkcja za pomocą "New", ta funkcja nadrzędna jest wykonywana, czego nie chcemy.
Oto wnioski na wynos
źródło