ECMA – Sebastians Blog https://sgaul.de Neues aus den Softwareminen Thu, 13 Mar 2014 20:34:51 +0000 de-DE hourly 1 https://wordpress.org/?v=6.1.7 https://sgaul.de/wp-content/uploads/2019/02/cropped-sgaul-2-1-32x32.jpg ECMA – Sebastians Blog https://sgaul.de 32 32 Javascript: prototype gegen __proto__ https://sgaul.de/2012/01/23/javascript-prototype-gegen-__proto__/ https://sgaul.de/2012/01/23/javascript-prototype-gegen-__proto__/#comments Mon, 23 Jan 2012 18:33:31 +0000 https://sgaul.de/?p=976 Immer wieder bin ich über zwei Javascript-Propertys gestolpert, die ich nicht wirklich zu unterscheiden wusste: Sowohl mit prototype wie auch mit __proto__ kann man auf den Prototype eines JS-Objekts zugreifen und diesen beispielsweise erweitern.

Prototypen in Javascript

Prototypen dienen in Javascript dazu, eine Art der Vererbung zu realisieren, die es aufgrund der nicht vorhandenen Klassen nicht direkt gibt. Objekte in Javascript haben einen Prototypen, diese wiederum können ebenfalls einen haben. Erzeugt man etwa ein leeres Objekt, hat dieses von Haus aus einige Eigenschaften:

var a = {};
console.log(a.toString()); // "[object Object]"

Da der Interpreter die Eigenschaft toString nicht in a finden kann, prüft er, ob er sie in dessen Prototypen findet (und ggf. in dessen Prototypen usw.). Der Prototyp von a ist (wenn nicht anders angegeben) ganz automatisch Object, welches die Methode toString bereitstellt.

Die Eigenschaft __proto__

Zwar ist dies kein ECMA-Standard, aber zumindest Chrome und Firefox vergeben jedem Objekt eine Eigenschaft __proto__, über welche man auf den Prototypen einer Objektinstanz zugreifen kann:

var a = {};
console.log(a.__proto__.constructor.name); // "Object"

Und prototype?

ECMA-Standard und viel verbreiteter ist aber die Eigenschaft prototype. Anders als __proto__ wird sie aber nicht für Objekte mitgeliefert, sondern für Funktionen:

// Kein prototype in leeren Objekt:
console.log(typeof ({}).prototype); // "undefined"
// Dafür in einer Funktion:
console.log(typeof (function(){}).prototype); // "object"

Nutzt man eine Funktion als Konstruktor, so ist der Prototyp des zurückgelieferten Objektes automatisch eine Referenz auf die Prototype-Eigenschaft der Funktion:

// Ein einfacher Konstruktor
function Person(name) {
    this.name = name;
}
// prototype der Funktion erweitern...
Person.prototype.greet = function() {
    console.log("Hello, my name is " 
                + this.name);
};

var peter = new Person("Peter");
// Prototyp ist prototype des Konstruktors:
peter.greet(); // "Hello, my name is Peter"

Kurz weitergeführt, zeigt das Beispiel noch mal den Unterschied zwischen __proto__ und prototype:

var paul = new Person("Paul");
paul.greet(); // "Hello, my name is Paul"

// paul ist Objekt, keine Funktion, hat 
// daher keine Eigenschaft prototype:
paul.prototype.greet = function() {
    console.log("Guten Tag, mein Name ist " 
                + this.name);
}; // Uncaught TypeError: 
   //   Cannot set property 'greet' of undefined

// Dafür aber die Eigenschaft __proto__
paul.__proto__.greet = function() {
    console.log("Guten Tag, mein Name ist " 
                + this.name);
};

paul.greet(); // "Guten Tag, mein Name ist Paul"
]]>
https://sgaul.de/2012/01/23/javascript-prototype-gegen-__proto__/feed/ 9