web-dev-qa-db-de.com

JavaScript-Vererbung: Object.create vs new

Was ist in JavaScript der Unterschied zwischen diesen beiden Beispielen:

Voraussetzung:

function SomeBaseClass(){
}

SomeBaseClass.prototype = {
    doThis : function(){
    },

    doThat : function(){
    }
}

Vererbungsbeispiel A mit Object.create:

function MyClass(){
}

MyClass.prototype = Object.create(SomeBaseClass.prototype);

Vererbung Beispiel B mit dem neuen Schlüsselwort

function MyClass(){
}

MyClass.prototype = new SomeBaseClass();

Beide Beispiele scheinen dasselbe zu tun. Wann würdest du dich für eines entscheiden?

Eine zusätzliche Frage: Betrachten Sie den Code unter link (Zeile 15), wo im Prototyp eine Referenz auf den eigenen Konstruktor der Funktion gespeichert wird. Warum ist das nützlich?

https://github.com/mrdoob/three.js/blob/master/src/loaders/ImageLoader.js

Auszug (wenn Sie den Link nicht öffnen möchten):

THREE.ImageLoader.prototype = {

    constructor: THREE.ImageLoader
}
116
ChrisRich

In Ihrer Frage haben Sie erwähnt, dass Both examples seem to do the same thing: Es stimmt überhaupt nicht, weil

Dein erstes Beispiel

function SomeBaseClass(){...}
SomeBaseClass.prototype = {
    doThis : function(){...},
    doThat : function(){...}
}
function MyClass(){...}
MyClass.prototype = Object.create(SomeBaseClass.prototype);

In diesem Beispiel erben Sie nur SomeBaseClass' prototype, aber was ist, wenn Sie eine Eigenschaft in Ihrer SomeBaseClass-Eigenschaft haben?

function SomeBaseClass(){ 
    this.publicProperty='SomeValue'; 
}

und wenn du es gerne benutzt

var obj=new MyClass();
console.log(obj.publicProperty); // undefined
​console.log(obj);​

Das obj-Objekt hat keine publicProperty-Eigenschaft wie in diesem Beispiel .

Dein zweites Beispiel

MyClass.prototype = new SomeBaseClass();

Es führt die constructor-Funktion aus, erstellt eine Instanz von SomeBaseClass und erbt das gesamte SomeBaseClass-Objekt. Also, wenn Sie verwenden

    var obj=new MyClass();
    console.log(obj.publicProperty); // SomeValue
    console.log(obj);​

In diesem Fall steht seine publicProperty-Eigenschaft auch für das obj-Objekt zur Verfügung, wie in diesem Beispiel .

Da der Object.create in einigen alten Browsern nicht verfügbar ist, können Sie in diesem Fall verwenden

if(!Object.create)
{
    Object.create=function(o){
        function F(){}
        F.prototype=o;
        return new F();
    }
}

Der obige Code fügt nur die Object.create-Funktion hinzu, falls diese nicht verfügbar ist. Sie können die Object.create-Funktion verwenden, und ich denke, der Code oben beschreibt, was Object.create tatsächlich tut. Ich hoffe, es wird irgendwie helfen.

109
The Alpha

Beide Beispiele scheinen dasselbe zu tun.

Das stimmt in deinem Fall.

Wann würdest du dich für eines entscheiden?

Wenn SomeBaseClass einen Funktionshauptteil hat, wird dieser mit dem Schlüsselwort new ausgeführt. Dies ist normalerweise nicht beabsichtigt - Sie möchten nur die Prototypkette einrichten. In einigen Fällen kann dies sogar zu ernsthaften Problemen führen, da Sie tatsächlich ein Objekt instanziieren, dessen private Variablen von allen MyClass-Instanzen gemeinsam genutzt werden, da sie die gleichen privilegierten Methoden erben. Andere Nebenwirkungen sind vorstellbar.

Daher sollten Sie generell Object.create bevorzugen. Es wird jedoch in einigen älteren Browsern nicht unterstützt. Aus diesem Grund sehen Sie die new- Annäherung viel zu häufig, da sie häufig keinen (offensichtlichen) Schaden anrichtet. Schau auch auf diese Antwort .

39
Bergi

Der Unterschied wird offensichtlich, wenn Sie Object.create() wie vorgesehen verwenden. Tatsächlich verbirgt es das prototype-Wort vollständig aus Ihrem Code. Es erledigt die Arbeit unter der Haube. Mit Object.create() können wir wie gehen

var base =  {
    doThis : function(){
    },

    doThat : function(){
    }
};

Und dann können wir andere Objekte daraus erweitern/erben

var myObject = Object.create( base );
// myObject will now link to "base" via the prototype chain internally

Dies ist also ein anderes Konzept, eine "objektorientiertere" Art des Inhertings. Es gibt keine "Konstruktorfunktion", die beispielsweise Object.create() verwendet. Aber natürlich können Sie einfach eine selbst definierte Konstruktorfunktion innerhalb dieser Objekte erstellen und aufrufen.

Ein Argument für die Verwendung von Object.create() ist, dass es möglicherweise mehr von natural zu mix / * erbt * von anderen Objekten aussieht als von Javascripts default way .

8
jAndy

Ich bin kein Experte für Java-Skript, aber hier ist ein einfaches Beispiel, um den Unterschied zwischen "Object.create" und "new" zu verstehen.

schritt 1: Erstellen Sie die übergeordnete Funktion mit einigen Eigenschaften und Aktionen.

function Person() {

this.name = 'venkat';

this.address = 'dallas';

this.mobile='xxxxxxxxxx'

}

Person.prototype.func1 = function () {

    return this.name + this.address;
}

schritt 2: Erstellen Sie eine untergeordnete Funktion (PersonSalary), die sich mit New - über die Person-Funktion erstreckt.

function PersonSalary() {
    Person.call(this);
}
PersonSalary.prototype = new Person();

PersonSalary();

schritt 3: Erstellen Sie eine zweite untergeordnete Funktion (PersonLeaves), die sich mit der Funktion Object.create über die Person-Funktion erstreckt.

function PersonLeaves() {
 Person.call(this);
}
PersonLeaves.prototype = Object.create(Person.prototype);


PersonLeaves();

// Überprüfen Sie nun beide Prototypen der untergeordneten Funktionen.

PersonSalary.prototype
PersonLeaves.prototype

beide untergeordneten Funktionen werden mit dem Prototyp "Person (übergeordnete Funktion)" verknüpft und können auf ihre Methoden zugreifen. Wenn Sie die untergeordnete Funktion mit new erstellen, wird ein brandneues Objekt mit allen übergeordneten Eigenschaften zurückgegeben, die wir nicht benötigen, und auch, wenn Sie eines erstellen Objekt oder Funktion mit "Neu" wird die übergeordnete Funktion ausgeführt, die wir nicht sein wollen.

Hier sind die Imbissbuden

wenn Sie nur an einige Methoden in der übergeordneten Funktion delegieren möchten und nicht möchten, dass ein neues Objekt erstellt wird, empfiehlt sich die Verwendung von Object.create.

0
Venkat