Welche Bedeutung hat die Eigenschaft des Javascript-Konstruktors?

Lesezeit: 6 Minuten

Benutzer-Avatar
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

Benutzer-Avatar
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

Benutzer-Avatar
Kamilo Martin

ein Fall, um den Konstruktor zu verwenden:

  1. 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;
        ...
    };
    
  2. 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:

    SubClass = function() {
        SubClass.superClass.constructor.call(this);
    };
    

also macht die Konstruktoreigenschaft hier Sinn.

  • 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

Benutzer-Avatar
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'

1010720cookie-checkWelche Bedeutung hat die Eigenschaft des Javascript-Konstruktors?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy