Frage zum Wiki-Artikel ‚new‘ - Prototypenbeschreibung
ToraxMalu
- frage zum wiki
- javascript
0 Rolf b
Moin!
Der Teilabschnitt mit new ist soweit noch klar und verständlich. Beginnt es dann aber mit dem Prototypen, explodiert einem der Kopf.
Könnt ihr das bitte etwas umformulieren? Ich versuche es auf jeden Fall morgen noch mal zu verstehen.
Merci
ToraxMalu
Tja, was soll man da sagen. Wer an OOP in der Art von C++ oder Java gewöhnt ist, muss bei Prototypen erstmal umdenken. Siehe den Link unten für Einstiegshilfen.
Das Thema "new" ist wirklich schwierig. Wenn man nur sagt "es aktiviert den Konstruktormodus einer Funktion und stellt das konstruierte Objekt in this
zur Verfügung", ist kaum was gesagt. Will man mehr sagen, steckt man sofort in einer Detailbetrachtung zu all den Quirks und Besonderheiten der Vererbungslehre von Javascript.
Für Konzepte wie "Was sind Prototypen" und "Wie funktioniert Vererbung in JavaScript" gibt's auch Tutorials. Schau mal hier unter Grundlegende Konzepte.
Rolf
Moin Rolf,
danke für den Link, der war mir entgangen.
Java? C++? Zeilennummern und Spaghetticode! ;)
Im Ernst: Dass new ein neues Objekt erstellt und dann in diesem Kontext die Funktion die Objekt-Bestandteile zusammenbaut und initialisiert, ist verständlich. Auch die Konstruktion mit this erschließt sich recht gut. Ich bekam nur gestern mit den Schachtelsätzen im zweiten Teil dieser Einführung Probleme. Ich versuche es noch mal, und gebe noch mal Feedback.
Der Vorteil von SelfHTML sind die immer wieder erklärten technischen Abläufe – nur manchmal wählen die Techniker für Neulinge die falschen Worte. Zumindest erlebe ich es selbst im Umgang mit Neulingen dieses Phänomen.
Cheers
ToraxMalu
Hallo ToraxMalul,
Der Vorteil von SelfHTML sind die immer wieder erklärten technischen Abläufe – nur manchmal wählen die Techniker für Neulinge die falschen Worte. Zumindest erlebe ich es selbst im Umgang mit Neulingen dieses Phänomen.
Dem entnehme ich, dass du selbst kein Neuling auf diesem Gebiet bist. Du kannst gern Änderungen am Artikel vornehmen. Eine einfachere (und dabei aber dennoch richtige) Formulierung ist sicherlich hilfreich.
Bis demnächst
Matthias
Okay, I give up. Der Code lässt erahnen, was gemeint ist, aber aus dem Text werde ich irgend wie nicht wirklich schlau. (Gemeint ist https://wiki.selfhtml.org/wiki/JavaScript/Operatoren/new#Beschreibung ab der Textstelle „Wenn es allerdings nur darum ginge, durch eine Funktion Objekte…“)
Oder habe ich das richtig verstanden:
Der Konstruktor darf nur kein anderes Objekt als Rückgabewert generieren / enthalten.
Okay, man werde nicht vorschnell die Flinte ins Korn werfen…
function a() {
this.Juhu = "Na Danke";
}
a.prototype.zeige = function () {
console.log(this.Juhu);
}
var b = new a;
Wenn ich die Ausgaben richtig interpretiere:
b; //Object b{"Na Danke"}
b.zeige(); //"Na Danke"
b.zeige; //function a.prototype.zeige()
scheine ich das Prinzip richtig zu verstehen. Kann das sein?
Tach!
scheine ich das Prinzip richtig zu verstehen. Kann das sein?
Ja, so geht das. Versuch doch mal nun, ob du den Text so formulieren kannst, dass du den gleich von Anfang an verstanden hättest.
dedlfix.
Ja, grundsätzlich schon. Ich hätte aber noch den Hinweis, dass man Konstruktorfunktionen per Konvention groß schreibt, um sie von normalen Funktionen zu unterscheiden.
Der entscheidende Punkt ist, dass jedes Objekt - wirklich jedes - ein verborgenes Property für den Prototyp hat. Dieses verborgene Property darf man übrigens NICHT mit der prototype-Eigenschaft einer Konstruktorfunktion verwechseln!
Manche Laufzeitumgebungen stellen dieses Property als __proto__
bereit - das ist aber non-standard. Der offizielle Weg zum Prototypen ist Object.getPrototypeOf(x)
. Und wenn man dann das Property foo des Objekts, das in bar steht, LESEN will, beginnt die JS Laufzeitumgebung mit der Suche.
und so weiter. Da Methoden nichts weiter sind als Funktionen, die als Eigenschaft eines Objekts gespeichert sind, funktioniert diese Suchkette für Datenproperties genauso wie für Methoden.
Wenn man ein Property schreiben will, wird immer nur am Objekt selbst geschrieben. Durch Operationen am Objekt selbst wird der Prototyp nicht verändert.
Nun stellt sich die Frage, wo der Wert herkommt, der im Prototyp in der property-Eigenschaft eines Objekts steht. Wird ein Objekt neu erzeugt, kann man den Prototypen explizit angeben:
var a = { foo: 17 };
var b = Object.create(a);
/// Object.getPrototypeOf(b) === a ---> true
a ist jetzt der Prototyp für b. a selbst hat auch einen Prototypen, und zwar das Objekt, das in Object.prototype zu finden ist. DIESES Objekt ist wiederum das einzige Objekt in der JavaScript-Objektsuppe, dessen Prototyp leer ist (genauer gesagt: das interne Prototyp-Property enthält den Wert null).
Object.create nutzt man aber eher selten. Im Normalfall verwendet man den new Operator. Oder ein Objektliteral, was aber Syntaxzucker ist für new Object(). Den new-Operator kannst Du Dir vereinfacht vorstellen als
var newObject = Object.create(Constructor.prototype);
Constructor.apply(newObject, constructorArgs);
return newObject;
Diese Vereinfachung lässt einiges außer Acht, vor allem den Rückgabewert der Konstruktorfunktion. Die Details stehen in der JavaScript-Spec, viel Spaß beim Decodieren...
Wenn Du eine eigene Funktion Bar
erzeugst, bekommt sie von JavaScript automatisch eine neues Objekt als prototype-Property zugewiesen. Dieses Prototypobjekt kannst Du erweitern, kannst es aber auch komplett überschreiben. Benutzt Du dann new Bar(), so bekommt das erzeugte Objekt den Prototypen Bar.prototype. Aber nicht vergessen, Bar.prototype ist NICHT der Prototyp von Bar.
// Object.getPrototypeOf(Object) === Object.prototype -> false
// Object.getPrototypeOf(Object) === Function.prototype -> true!
var a = { foo:17 };
// Object.getPrototypeOf(a) === Object.prototype -> true
var b = Object.create(a);
// Object.getPrototypeOf(a) === a -> true
function Bar = function() { };
Bar.prototype = { baz:99 };
var c = new Bar();
// Object.getPrototypeOf(c) === Bar.prototype -> true
// Object.getPrototypeOf(c) === Object.getPrototypeOf(Bar) -> false
// Object.getPrototypeOf(Bar) === Object.getPrototypeOf(Function) -> true
Interessant ist auch die Frage, ob es sinnvoller ist, Methoden am Prototyp zu definieren oder sie in der Konstruktorfunktion als Eigenschaften zuzuweisen. Beides geht, aber der Effekt ist unterschiedlich.
Das class Keyword von ECMAScript 6 ist übrigens nur Syntaxzucker für eine Konstruktorfunktion.
So, ich hoffe, dass ich jetzt alle Klarheiten endgültig beseitigt habe. Es steht auch alles im WIKI, aber manchmal hilft auch eine andere Formulierung des gleichen Sachverhalts :)
Rolf
/me murmelt: Oh ja, die Klarheiten sich wirklich beseitigt :D
Ich habe mal den Bereich umformuliert. Schaut es euch bitte an, ob ich da in meinem Halbwissen Müll geschrieben oder es besser getroffen habe. Der Punk mit lokalen Variablen könnte vielleicht noch erwähnt werden, wobei ich aus meiner Warte gerade keinen Sinn darin sehe. Sind Objekte-Eigenschaften nicht generell von außen erreichbar und eine Kapselung erst durch eine Funktion möglich?
/me murmelt: Oh ja, die Klarheiten sich wirklich beseitigt :D
Der Punk mit lokalen Variablen ...
Made My Day :D
/me murmelt: Oh ja, die Klarheiten sich wirklich beseitigt :D
Der Punk mit lokalen Variablen ...
Made My Day :D
Schön, wenn ich deinen Tag versüßte… :D Aber um ehrlich zu sein, war ich von deinen Ausführungen genauso erschlagen, wie von den Schachtelsätzen in dem Artikel.
Cheers.
Hast Du mal den hier:
https://wiki.selfhtml.org/wiki/JavaScript/Vererbung
gelesen? Da wird auf Prototypen und Vererbung intensiv eingegangen. Wenn Du diesen Artikel für verständlicher hältst, dann könnte man überlegen, den Artikel zu "new" massiv zu beschneiden und statt dessen auf den Vererbung-Artikel zu verlinken.
Das Thema mit Objekteigenschaften wird in einem Nachbarartikel dazu behandelt, dass muss man unter new nicht bringen.
Rolf
Weia - und dafür habe ich mich 1¹/₂ Tage durchgebissen‽
Da könnte man wirklich einiges aus dem new-Artikel entfernen und auf diese Seite verweisen. Nur die Prototypenerklärung, in welcher Reihenfolge new mit dem Prototypen arbeitet und die Gefahr mit return {} in der Konstruktor-Funktion sollten unbedingt unter new erhalten bleiben.