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
}
Author: Boann, 2012-10-24

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.

 109
Author: The Alpha,
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

Oba przykłady wydają się robić to samo.

To prawda w Twoim przypadku.
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.

 39
Author: Bergi,
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 .

 8
Author: jAndy,
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.

 0
Author: Venkat,
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