Dziedziczenie JavaScript: obiekt.create vs new
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 użycie obiektu.utworzyć:
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ś jedno nad drugim?
Dodatkowe pytanie: Rozważ kod w poniższym linku (linia 15), gdzie odniesienie do konstruktora funkcji jest przechowywane w prototypie. Dlaczego to przydatne?
Https://github.com/mrdoob/three.js/blob/master/src/loaders/ImageLoader.js
Fragment (jeśli nie chcesz otworzyć linku):
THREE.ImageLoader.prototype = {
constructor: THREE.ImageLoader
}
4 answers
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
function SomeBaseClass(){...}
SomeBaseClass.prototype = {
doThis : function(){...},
doThat : function(){...}
}
function MyClass(){...}
MyClass.prototype = Object.create(SomeBaseClass.prototype);
W tym przykładzie po prostu dziedziczysz SomeBaseClass' prototype
, ale co, jeśli masz własność w swoim SomeBaseClass
, Jak
function SomeBaseClass(){
this.publicProperty='SomeValue';
}
I jeśli używasz go jak
var obj=new MyClass();
console.log(obj.publicProperty); // undefined
console.log(obj);
Obiekt obj
nie będzie posiadał właściwości publicProperty
, takiej jak w tym przykładzie.
Twój drugi przykład
MyClass.prototype = new SomeBaseClass();
Wykonuje funkcję constructor
, tworząc instancję SomeBaseClass
i dziedziczenie całego SomeBaseClass
obiektu. Tak więc, jeśli używasz
var obj=new MyClass();
console.log(obj.publicProperty); // SomeValue
console.log(obj);
W tym przypadku jego właściwość publicProperty
jest również dostępna dla obj
obiektu jak w tym przykładzie.
Ponieważ Object.create
nie jest dostępny w niektórych starych przeglądarkach, w takim przypadku możesz użyć
if(!Object.create)
{
Object.create=function(o){
function F(){}
F.prototype=o;
return new F();
}
}
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 to, co Object.create
faktycznie robi. Mam nadzieję, że to w jakiś sposób pomoże.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-29 13:38:28
To prawda w Twoim przypadku.Oba przykłady wydają się robić to samo.
Kiedy wybrałbyś jedno nad drugim?
Gdy SomeBaseClass
mA ciało funkcji, zostanie to wykonane za pomocą słowa kluczowego new
. Zazwyczaj 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 prywatnym zasięgu są współdzielone przez wszystkie MyClass
instancje, ponieważ dziedziczą te same uprzywilejowane metody. Inne skutki uboczne są możliwe do wyobrażenia.
Więc generalnie powinieneś preferować Object.create
. Jednak nie jest on obsługiwany w niektórych starszych przeglądarkach, co jest powodem, dla którego widzisz podejście new
zbyt częste, ponieważ często nie wyrządza (oczywistej) szkody. Zajrzyj również do tej odpowiedzi.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:55:03
Różnica staje się oczywista, jeśli używasz Object.create()
zgodnie z przeznaczeniem. Właściwie, to całkowicie ukryje prototype
słowo z twojego kodu, to wykona robotę pod maską. Używając Object.create()
, możemy przejść jak
var base = {
doThis : function(){
},
doThat : function(){
}
};
I wtedy możemy rozszerzyć / dziedziczyć inne obiekty z tego
var myObject = Object.create( base );
// myObject will now link to "base" via the prototype chain internally
Jest to więc kolejna koncepcja, bardziej "obiektowo zorientowany" sposób dziedziczenia. Nie ma "funkcji konstruktora" po wyjęciu z pudełka, na przykład używając Object.create()
. Ale oczywiście można po prostu stworzyć i nazwać siebie zdefiniowanym funkcja konstruktora wewnątrz tych obiektów.
Jednym z argumentów przemawiających za użyciem Object.create()
jest to, że może wyglądać bardziej naturalnie na mix /*inherit* od innych obiektów, niż użycie Javascripts domyślny sposób .
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-10-23 23:17:17
Nie jestem ekspertem w java script, ale tutaj jest prosty przykład, aby zrozumieć różnicę między " obiekt.Utwórz " i "Nowy"..
Krok 1: Utwórz funkcję nadrzędną z niektórymi właściwościami i akcjami..
function Person() {
this.name = 'venkat';
this.address = 'dallas';
this.mobile='xxxxxxxxxx'
}
Person.prototype.func1 = function () {
return this.name + this.address;
}
Krok 2: Utwórz funkcję potomną (PersonSalary), która rozszerza się nad funkcją Person używając słowa kluczowego New..
function PersonSalary() {
Person.call(this);
}
PersonSalary.prototype = new Person();
PersonSalary();
Krok 3: Utwórz drugą funkcję potomną (PersonLeaves), która rozszerza się nad funkcją Person przy użyciu obiektu .create słowo kluczowe..
function PersonLeaves() {
Person.call(this);
}
PersonLeaves.prototype = Object.create(Person.prototype);
PersonLeaves();
// Teraz sprawdź prototypy obu funkcji potomnych.
PersonSalary.prototype
PersonLeaves.prototype
Obie te funkcje potomne będą linkować do prototypu Person (parent function) i będą miały dostęp do jego metod, ale jeśli utworzysz funkcję potomną używając new, zwróci ona zupełnie nowy obiekt ze wszystkimi właściwościami nadrzędnymi, których nie potrzebujemy, a także gdy stworzysz dowolny obiekt lub funkcję używając "New", zostanie wykonana funkcja nadrzędna, której nie chcemy być.
Oto dania na wynos
Jeśli po prostu chcesz delegować do niektórych metod w funkcji rodzica i nie chcesz tworzyć nowego obiektu za pomocą obiektu.Tworzenie jest najlepszym sposobem.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-14 02:42:14