Ich bin kürzlich auf die Object.create()
Methode in JavaScript gestoßen und versuche herauszufinden, wie sie sich vom Erstellen einer neuen Instanz eines Objekts new SomeFunction()
unterscheidet und wann Sie eine über der anderen verwenden möchten.
Betrachten Sie das folgende Beispiel:
var test = {
val: 1,
func: function() {
return this.val;
}
};
var testA = Object.create(test);
testA.val = 2;
console.log(test.func()); // 1
console.log(testA.func()); // 2
console.log('other test');
var otherTest = function() {
this.val = 1;
this.func = function() {
return this.val;
};
};
var otherTestA = new otherTest();
var otherTestB = new otherTest();
otherTestB.val = 2;
console.log(otherTestA.val); // 1
console.log(otherTestB.val); // 2
console.log(otherTestA.func()); // 1
console.log(otherTestB.func()); // 2
Beachten Sie, dass in beiden Fällen das gleiche Verhalten beobachtet wird. Es scheint mir, dass die Hauptunterschiede zwischen diesen beiden Szenarien sind:
- Das in verwendete Objekt
Object.create()
bildet tatsächlich den Prototyp des neuen Objekts, während innew Function()
den deklarierten Eigenschaften / Funktionen nicht der Prototyp gebildet wird. - Sie können mit der
Object.create()
Syntax keine Verschlüsse erstellen, wie Sie es mit der funktionalen Syntax tun würden. Dies ist angesichts des lexikalischen Bereichs (vs Block) von JavaScript logisch.
Sind die obigen Aussagen richtig? Und vermisse ich etwas? Wann würden Sie eins über das andere verwenden?
BEARBEITEN: Link zur jsfiddle-Version des obigen Codebeispiels: http://jsfiddle.net/rZfYL/
Antworten:
Ja, erstellt
Object.create
ein Objekt, das direkt von dem als erstes Argument übergebenen Objekt erbt.Bei Konstruktorfunktionen erbt das neu erstellte Objekt vom Prototyp des Konstruktors, z.
Im obigen Beispiel
o
erbt direkt vonSomeConstructor.prototype
.Hier gibt es einen Unterschied:
Object.create
Sie können ein Objekt erstellen, das von nichts erbt .Object.create(null);
Wenn Sie jedoch festlegen, dassSomeConstructor.prototype = null;
das neu erstellte Objekt von etwas erbtObject.prototype
.Nun, Sie können Abschlüsse erstellen, z. B. mit dem Argument der Eigenschaftsbeschreibungen:
Beachten Sie, dass ich über die ECMAScript 5th Edition-
Object.create
Methode spreche , nicht über die Crockford-Unterlegscheibe.Die Methode wird in den neuesten Browsern nativ implementiert. Überprüfen Sie diese Kompatibilitätstabelle .
quelle
foo;
in der aktuellen behoben ist lexikalische Umgebung . 2) Um die Vererbung auf einfache Weise zu implementieren, ist es ein wirklich mächtiges Konstrukt. IMO Ich würde es verwenden, weil es wirklich einfach und leicht ist, aber für Produktionscode müssen wir noch einige Zeit warten, bis ES5 weitgehend unterstützt wird. Über fehlende Funktionen, die Tatsache, dass ein "makelloses" Objekt erstelltObject.create(null);
wurde, fehlte, ist es wirklich nützlich, zuverlässige Hash-Tabellen-ähnliche Objekte zu implementieren ...Object.create(null)
bedeutet also, dass SiehasOwnProperty()
beim Iterieren keinen Mist verwenden müssen, weil er keinen erbt ??? Das gefällt mir - danke. Natürlich wird es immerhasOwnProperty
noch jeder tun, da nicht jeder es nutzen wird,Object.create(null)
also bin ich mir nicht sicher, ob es ein wirklicher Vorteil ist ... Bisher habe ich die anderen "Vorteile" alsObject.create()
völlig nicht überzeugend empfunden.Ganz einfach gesagt,
new X
istObject.create(X.prototype)
mit zusätzlich dieconstructor
Lauffunktion. (Und geben Sie dem tatsächlichen Objektconstructor
die Chance,return
das Ergebnis des Ausdrucks zu sein, anstattthis
.)Das ist es. :) :)
Der Rest der Antworten ist nur verwirrend, weil anscheinend niemand sonst die Definition von beidem liest
new
. ;)quelle
Hier sind die Schritte, die intern für beide Aufrufe ausgeführt werden:
(Hinweis: Der einzige Unterschied besteht in Schritt 3)
new Test()
::new Object()
obj erstellenobj.__proto__
aufTest.prototype
return Test.call(obj) || obj; // normally obj is returned but constructors in JS can return a value
Object.create( Test.prototype )
new Object()
obj erstellenobj.__proto__
aufTest.prototype
return obj;
Object.create
Der Konstruktor wird also im Grunde nicht ausgeführt.quelle
new
Grundsätzlich werden alle Funktionen dupliziert, währendObject.create
dies nicht der Fall ist.Lassen Sie mich versuchen zu erklären (mehr im Blog ):
Car
Konstruktorvar Car = function(){}
, das ist , wie die Dinge sind intern: Wir haben einen{prototype}
versteckten Link zuFunction.prototype
dem nicht zugänglich ist und eineprototype
Verbindung zuCar.prototype
dem ist zugänglich und verfügt über eine tatsächlicheconstructor
vonCar
. Sowohl Function.prototype als auch Car.prototype haben versteckte Links zuObject.prototype
.Wenn wir mit dem
new
Operator und dercreate
Methode zwei äquivalente Objekte erstellen möchten, müssen wir dies folgendermaßen tun:Honda = new Car();
undMaruti = Object.create(Car.prototype)
. Was ist los?Honda = new Car();
- Wenn Sie ein Objekt wie dieses erstellen,{prototype}
wird auf versteckte Eigenschaften verwiesenCar.prototype
. Hier wird das{prototype}
Honda-Objekt also immer seinCar.prototype
- wir haben keine Möglichkeit, die{prototype}
Eigenschaft des Objekts zu ändern . Was ist, wenn ich den Prototyp unseres neu erstellten Objekts ändern möchte?Maruti = Object.create(Car.prototype)
- Wenn Sie ein Objekt wie dieses erstellen, haben Sie eine zusätzliche Option, um die{prototype}
Eigenschaft Ihres Objekts auszuwählen . Wenn Sie Car.prototype als möchten, übergeben Sie{prototype}
es als Parameter in der Funktion. Wenn Sie keine{prototype}
für Ihr Objekt möchten, können Sienull
wie folgt übergeben :Maruti = Object.create(null)
.Schlussfolgerung - Mit der Methode haben
Object.create
Sie die Freiheit, Ihre Objekteigenschaft auszuwählen{prototype}
. Innew Car();
hast du diese Freiheit nicht.Bevorzugter Weg in OO JavaScript:
Angenommen, wir haben zwei Objekte
a
undb
.Angenommen, es
a
gibt einige Methoden, auf dieb
auch zugegriffen werden soll. Dafür benötigen wir eine Objektvererbung (a
sollte nur dann der Prototyp sein,b
wenn wir Zugriff auf diese Methoden wünschen). Wenn wir die Prototypen vona
und überprüfen, werdenb
wir feststellen, dass sie den Prototyp gemeinsam habenObject.prototype
.Problem - wir wollen ein Objekt
a
als Prototyp vonb
, aber hier haben wir ein Objektb
mit dem Prototyp erstelltObject.prototype
. Lösung - ECMAScript 5 wurde eingeführtObject.create()
, um eine solche Vererbung leicht zu erreichen. Wenn wir ein Objektb
wie dieses erstellen :dann,
Wenn Sie also objektorientiertes Scripting ausführen,
Object.create()
ist dies für die Vererbung sehr nützlich.quelle
a.isPrototypeOf(b);
das zurückkehren wird,false
was richtig ist, weil beide Objekte unterschiedlich sind und auf unterschiedlichen Speicher zeigen. Der richtige Weg, dies mit demnew
Bediener zu tun , ist hier. - jsfiddle.net/167onunp .Diese:
und
sind ziemlich ähnlich. Ein wichtiger Unterschied besteht darin, dass
new Foo
tatsächlich Konstruktorcode ausgeführt wird, währendObject.create
Code wie zBeachten Sie, dass Sie mit der Zwei-Parameter-Version von
Object.create()
viel leistungsfähigere Dinge tun können.quelle
Object.create
in seiner einfachsten Form Konstruktorfunktionen aus Ihrem Code weglassen können, während Sie die Vererbung von Prototypen nutzen.Der Unterschied ist die sogenannte "pseudoklassische vs. prototypische Vererbung". Der Vorschlag ist, nur einen Typ in Ihrem Code zu verwenden und nicht beide zu mischen.
Stellen Sie sich bei der pseudoklassischen Vererbung (mit dem Operator "new") vor, Sie definieren zuerst eine Pseudoklasse und erstellen dann Objekte aus dieser Klasse. Definieren Sie beispielsweise eine Pseudoklasse "Person" und erstellen Sie dann "Alice" und "Bob" aus "Person".
Bei der prototypischen Vererbung (mit Object.create) erstellen Sie direkt eine bestimmte Person "Alice" und anschließend eine andere Person "Bob" mit "Alice" als Prototyp. Hier gibt es keine "Klasse"; Alle sind Objekte.
Intern verwendet JavaScript "prototypische Vererbung". Der "pseudoklassische" Weg ist nur etwas Zucker.
Unter diesem Link finden Sie einen Vergleich der beiden Möglichkeiten.
quelle
Zusammenfassung:
1) mit
new
Schlüsselwort gibt es zwei Dinge zu beachten;a) Funktion wird als Konstruktor verwendet
b)
function.prototype
Objekt wird an die__proto__
Eigenschaft übergeben ... oder wo__proto__
es nicht unterstützt wird, ist es der zweite Ort, an dem das neue Objekt nach Eigenschaften sucht2) mit
Object.create(obj.prototype)
dir konstruierst du ein Objekt (obj.prototype
) und übergibst es an das beabsichtigte Objekt .. mit dem Unterschied, dass jetzt auch neue Objekte__proto__
auf obj.prototype verweisen (bitte verweise auf xj9)quelle
Objekterstellungsvarianten.
Variante 1 : ' new Object () ' -> Objektkonstruktor ohne Argumente.
Variante 2 : ' neues Objekt (Person) ' -> Objektkonstruktor mit Argument.
Variante 3.1 : ' Object.create (Person) '. Verwenden Sie Object.create mit dem einfachen Objekt 'person'. 'Object.create (person)' erstellt (und gibt) ein neues leeres Objekt zurück und fügt dem neuen leeren Objekt die Eigenschaft '__proto__' hinzu. Diese Eigenschaft '__proto__' zeigt auf das Objekt 'person'.
Variante 3.2 : ' Object.create (Object.prototype) '. Verwenden Sie Object.create mit integriertem Objekt -> 'Object.prototype'. 'Object.create (Object.prototype)' erstellt (und gibt) ein neues leeres Objekt zurück und fügt dem neuen leeren Objekt die Eigenschaft '__proto__' hinzu. Diese Eigenschaft '__proto__' zeigt auf das Objekt 'Object.prototype'.
Variante 4 : ' new SomeFunction () '
quelle
Intern
Object.create
macht das:Die Syntax nimmt nur die Illusion weg, dass JavaScript die klassische Vererbung verwendet.
quelle
Object.create
Methode bietet viel mehr als das. Sie können Eigenschaften mithilfe von Eigenschaftsbeschreibungen definieren und ein Objekt erstellen, das nichts erbt (Object.create(null);
). Diese Art von Shims sollte vermieden werden, da Sie dies nicht wirklich emulieren können Verhalten auf ES3. Weitere InformationenObject.create
.Entsprechend dieser Antwort und diesem Video macht das
new
Schlüsselwort folgende Dinge:Erstellt ein neues Objekt.
Verknüpft neues Objekt mit der Konstruktorfunktion (
prototype
).Legt einen
this
variablen Punkt auf das neue Objekt.Führt die Konstruktorfunktion mit dem neuen Objekt und der impliziten Ausführung aus
return this
.Weist der Eigenschaft des neuen Objekts den Namen der Konstruktorfunktion zu
constructor
.Object.create
führt nur1st
und2nd
Schritte !!!quelle