Krautkanal.com

Veröffentlicht am 2015-06-16 12:19:57 in /prog/

/prog/ 7235: Bernd wie entferne ich Eigenschaften aus dem Prototyp i...

jqueryalmeida Avatar
jqueryalmeida:#7235

Bernd wie entferne ich Eigenschaften aus dem Prototyp in der unteren Code-Variante?

function Foo(){}

Foo.prototype.bar = 42;

var foo = new Foo;

delete Foo.prototype.bar;

console.log(foo.bar);

>undefined, so soll es sein


function Foo(){

this.bar = 42;

}

var foo = new Foo;

delete Foo.prototype.bar;

console.log(foo.bar);

>42, wzf?

rcass Avatar
rcass:#7236

Beim Auswerten eines Ausdrucks der Form foo.bar guckt die VM zuerst, ob im Dictionary "foo" der Schlüssel "bar" enthalten ist und gibt dann ggf. den entsprechenden Wert zurück. Andernfalls wird im Protoyp (foo.__proto__) nach dem Schlüssel gesucht und ggf. zurückgegeben. Andernfalls wird im Eltern-Prototyp (foo.__proto__.__proto__) nach dem Schlüssel gesuch und ggf. zurückgegeben. Usw., bis man beim Prototyp von Object angekommen ist. Ist der Schlüssel dort nicht drin, wird ein entsprechender Fehler erzeugt.

Das nennt sich Prototypen-Kette und ist die Umsetzung des Vererbungskonzepts in Javascript. Mit Object.create() kannst du selbst einen Prototypen erzeugen, der nicht direkt von Object abeleitet ist.

aio___ Avatar
aio___:#7237

>>7236
Um das noch ein bisschen spezifischer auf deine Frage zu beziehen:
Jedes mit new erzeugte Objekt ist in Javascript auch gleichzeitig ein Dictionary. Wenn du in irgend einer Methode (egal ob Constructor, eine Methode des Prototyps, oder sonst was) per this etwas zuweist, dann landen die Daten dafür immer im Dictionary des Objekts, nie im Prototypen.

Was Bernd damit meint:
function Foo() {}
Foo.prototype.bar = 42;
Foo.prototype.test = function() { this.bar = 99; }

var x = Foo(), y = Foo();
console.log(x.bar); // 42
console.log(y.bar); // 42
x.test();
console.log(x.bar); // 99
console.log(y.bar); // 42

Jetzt ist x.bar ein Key im Dictionary x, während y.bar weiterhin ein Key im Prototypen von Foo ist.

starburst1977 Avatar
starburst1977:#7238

>>7235

Da ist gar nichts "wzf" dran, beim zweiten Beispiel setzt du ja ein Property auf dem aktuellen Objekt mittels "this.bar" und nicht auf dem Prototypen. Dann überprüfst du auch das aktuelle Objekt (und nicht den Prototypen) mit "foo.bar" und wunderst dich, dass der Wert noch da ist?

michaelkoper Avatar
michaelkoper:#7243

Danke Bernd,

Bernd hat da wohl bei dem Prototyping was Grundlegendes falsch verstanden. Also wenn Bernd eine Eigenschaft für alle Instanzen ändern möchte muss er diese immer im Prototypen hinterlegen und nicht in der Konstruktorfunktion, also so:


function Car() {}

Car.prototype.doors = 4;

var vw = new Car();
var bmw = new Car();
var audi = new Car();

vw.doors; //4
bmw.doors; //4
audi.doors; //4


Bernd dachte die Konstruktorfunktion wäre der Prototyp... (.___. )

Stattdessen ist es wohl eher Bild verwandt.

andina Avatar
andina:#7253

>>7243

Ich denke man kann es sich am einfachsten so vorstellen: Das .prototype-Property ist ein Objekt, welches den "Prototypen", also eine gemeinsame Vorlage für alle zu erstellenden Instanzen des Objekts definiert.

Der Prototyp wird also immer geteilt - eine Änderung dort wirkt sich auf alle Instanzen aus - während mit this definierte Properties immer nur für die jeweilige Instanz gelten. Deswegen soll man Methoden auch in .prototype definieren und nicht im Konstruktor. Denn dort würden sie für jede Instanz einzeln gespeichert, was für die Performance nicht sonderlich gut ist.

Dein Beispiel scheint mir korrekt zu sein, allerdings wäre es evtl. ratsam, eine Eigenschaft wie doors pro Instanz zu definieren (falls du mal Car-Objekte mit 2 Türen benötigst). Denn eine Änderung von Car.prototype.doors würde sich auf alle Instanzen auswirken...

Neuste Fäden in diesem Brett: