Welche Bedeutung hat die Eigenschaft des Javascript-Konstruktors?
Lesezeit: 6 Minuten
aaa90210
Der Versuch, sich kopfüber um Javascripts Version von OO zu beugen … und, wie viele andere, in Verwirrung darüber zu geraten constructor Eigentum. Insbesondere die Bedeutung der constructor Eigentum, da ich es anscheinend nicht beeinflussen kann. Z.B:
function Foo(age) {
this.age = age;
}
function Bar() {
Foo.call(this, 42);
this.name = "baz";
}
Bar.prototype = Object.create(Foo.prototype);
var b = new Bar;
alert(b.constructor); // "Foo". That's OK because we inherit `Foo`'s prototype.
alert(b.name); // "baz". Shows that Bar() was called as constructor.
alert(b.age); // "42", inherited from `Foo`.
Im obigen Beispiel das Objekt b scheint den richtigen Konstruktor aufgerufen zu haben (Bar) – und er erbt die Alterseigenschaft von Foo. Warum also schlagen viele Leute vor, dass dies ein notwendiger Schritt ist:
Bar.prototype.constructor = Bar;
Ganz klar das Richtige Bar Konstrukteur war wird beim Bau aufgerufen b, welche Auswirkungen hat diese Prototypeneigenschaft? Ich bin neugierig zu wissen, welchen praktischen Unterschied es tatsächlich macht, die Konstruktor-Eigenschaft „richtig“ festgelegt zu haben – da ich nicht sehen kann, dass es einen Einfluss darauf hat, welcher Konstruktor tatsächlich aufgerufen wird, nachdem ein Objekt erstellt wurde.
Ich habe die Beziehung zwischen Prototyp und Konstruktor erklärt unter: stackoverflow.com/a/23877420/895245
– Ciro Santilli Путлер Капут 六四事
5. September 2015 um 9:09 Uhr
Die vorherigen Antworten hier sagen (auf verschiedene Weise), dass der Wert der constructor -Eigenschaft wird von nichts in JavaScript selbst verwendet. Das war richtig, als diese Antworten geschrieben wurden, aber ES2015 und höher haben begonnen, es zu verwenden constructor für Sachen.
Das constructor Eigentum der prototype Die Eigenschaft einer Funktion soll auf die Funktion zurückweisen, damit Sie ein Objekt fragen können, was es konstruiert hat. Es wird automatisch als Teil der Erstellung eines herkömmlichen Funktionsobjekts oder eines Klassenkonstruktorobjekts eingerichtet (Einzelheiten).
function TraditionalFunction() {
}
console.log(TraditionalFunction.prototype.constructor === TraditionalFunction); // true
class ExampleClass {
}
console.log(ExampleClass.prototype.constructor === ExampleClass); // true
Pfeilfunktionen haben kein a prototype Eigentum, also haben sie es nicht prototype.constructor.
Jahrelang sagte die JavaScript-Spezifikation nur, dass die constructor Eigenschaft wäre dort und hätte standardmäßig diesen Wert (einen Link zurück zur Funktion). Aber ab ES2015 hat sich das geändert, und verschiedene Operationen in der Spezifikation verwenden jetzt tatsächlich die constructor Eigentum, wie z diese, diese, dieseund diese.
Wenn Sie also Konstruktorfunktionen einrichten, die Vererbungsketten aufbauen, sollten Sie am besten sicherstellen, dass die constructor Eigenschaft bezieht sich auf die entsprechende Funktion. Siehe meine Antwort hier für Beispiele usw.
Ich stimme zu, dass die constructor Die Eigenschaft ist nicht sehr nützlich, aber das Erben vom Prototyp eines anderen Objekts kann extrem leistungsfähig sein, und ich würde das überhaupt nicht entmutigen.
– Tim unten
25. Oktober 2010 um 9:38 Uhr
Danke – es ist vielleicht nicht idiomatisch, aber viele der Tutorials im Internet (und Fragen und Antworten zu SE) schlagen vor, dass die Verwendung dieser bestimmten Methode “erforderlich” ist – als ob das gesamte Prototypmodell kaputt geht, wenn Sie es nicht verwenden.
– aaa90210
25. Oktober 2010 um 9:47 Uhr
Oh, tut mir leid, wenn es so rübergekommen ist. Das Vererben von Prototypen eines anderen Objekts ist nicht das Problem; Ändern der Konstruktor-Eigenschaft ist.
– Jakob
25. Oktober 2010 um 9:49 Uhr
@Jakob, du sagst “Die constructor Eigentum nicht keine besonderen Effekte in Ihrem Programm hervorrufen, außer dass Sie darin nachsehen können, welche Funktion in Verbindung mit dem Operator verwendet wurde new um Ihr Objekt zu erstellen. Wenn Sie eingegeben haben new Bar() es wird sein Bar und du hast getippt new Fooes wird sein Foo.” Das ist nicht richtig. Die constructor Eigenschaft bezieht sich auf die Funktion, die ein bestimmtes Objekt erstellt hat Prototypwie im Beispiel sogar vom OP gesehen.
– Behrang
11. Juni 2013 um 16:11 Uhr
“Sie können sich ansehen, welche Funktion in Verbindung mit dem Operator new verwendet wurde, um Ihr Objekt zu erstellen”. Nein, das kannst du nicht. Es gibt auch einen Hinweis auf die Funktion, mit der ein Prototypobjekt zuerst in Verbindung gebracht wurde (vorausgesetzt, die Konstrukteur -Eigenschaft wurde nicht auf einen anderen Wert gesetzt). Es sagt Ihnen nichts Bestimmtes über die Instanz aus, die es erbt.
– RobG
20. Mai 2014 um 2:10 Uhr
Golem
Einer der Anwendungsfälle, in denen Sie das möchten prototype.constructor Eigentum zu überleben prototype Neuzuweisung von Eigenschaften ist, wenn Sie eine Methode für die definieren prototype die neue Instanzen desselben Typs wie die angegebene Instanz erzeugt. Beispiel:
function Car() { }
Car.prototype.orderOneLikeThis = function() { // Clone producing function
return new this.constructor();
}
Car.prototype.advertise = function () {
console.log("I am a generic car.");
}
function BMW() { }
BMW.prototype = Object.create(Car.prototype);
BMW.prototype.constructor = BMW; // Resetting the constructor property
BMW.prototype.advertise = function () {
console.log("I am BMW with lots of uber features.");
}
var x5 = new BMW();
var myNewToy = x5.orderOneLikeThis();
myNewToy.advertise(); // => "I am BMW ..." if `BMW.prototype.constructor = BMW;` is not
// commented; "I am a generic car." otherwise.
Warum hast du es nicht vorgezogen Object.setPrototypeOf(BMW.prototype, Car.prototype); anstatt BMW.prototype = Object.create(Car.prototype);?
– Übertausch
30. Oktober 2017 um 5:41 Uhr
@overexchange Ja, das würde den Einstellungskonstruktorschritt reduzieren. Das sollten wir nutzen, oder??
– Suraj Jain
15. April 2019 um 14:59 Uhr
Kamilo Martin
ein Fall, um den Konstruktor zu verwenden:
dies ist eine der gängigen Realisierungen der Vererbung:
Function.prototype.extend = function(superClass,override) {
var f = new Function();
f.prototype = superClass.prototype;
var p = this.prototype = new f();
p.constructor = this;
this.superclass = superClass.prototype;
...
};
diese new f() würde den Konstruktor von superClass nicht aufrufen. Wenn Sie also eine Unterklasse erstellen, müssen Sie möglicherweise zuerst die superClass aufrufen, wie folgt:
Warum hast du es nicht vorgezogen Object.setPrototypeOf(BMW.prototype, Car.prototype); anstatt BMW.prototype = Object.create(Car.prototype);?
– Übertausch
30. Oktober 2017 um 5:41 Uhr
@overexchange Ja, das würde den Einstellungskonstruktorschritt reduzieren. Das sollten wir nutzen, oder??
– Suraj Jain
15. April 2019 um 14:59 Uhr
jsbicht
Die Konstruktor-Eigenschaft zeigt auf den Konstruktor, der zum Erstellen der Objektinstanz verwendet wurde. Wenn Sie ‘new Bar()’ eingegeben haben, wird es ‘Bar’ sein und Sie haben ‘new Foo()’ eingegeben, es ist ‘Foo’.
Aber wenn Sie den Prototyp setzen, ohne den Konstruktor zu setzen, würden Sie so etwas bekommen:
function Foo(age) {
this.age = age;
}
function Bar() {
this.name = "baz";
}
Bar.prototype = new Foo(42);
var one = new Bar();
console.log(one.constructor); // 'Foo'
var two = new Foo();
console.log(two.constructor); // 'Foo'
Um den Konstruktor tatsächlich auf den Konstruktor zu setzen, der zum Erstellen des Objekts verwendet wurde, müssen wir den Konstruktor auch setzen, während wir den Prototyp wie folgt setzen:
function Foo(age) {
this.age = age;
}
function Bar() {
this.name = "baz";
}
Bar.prototype = new Foo(42);
Bar.prototype.constructor = Bar;
var one = new Bar();
console.log(one.constructor); // 'Bar'
var two = new Foo();
console.log(two.constructor); // 'Foo'
10107200cookie-checkWelche Bedeutung hat die Eigenschaft des Javascript-Konstruktors?yes
Ich habe die Beziehung zwischen Prototyp und Konstruktor erklärt unter: stackoverflow.com/a/23877420/895245
– Ciro Santilli Путлер Капут 六四事
5. September 2015 um 9:09 Uhr