Oliver Schmidt

Prototypische Vererbung in JavaScript

2012-03-31

Note: This post is from my old blog and thus written in German and potentially obsolete.

Nachdem ich mich in vier meiner letzten Artikel mit der pseudoklassischen Vererbung in JavaScript beschäftigt hatte, gibt es diesmal einen kurzen Einstieg in die prototypische Vererbung.

Das Vorhandensein eines new-Operators mag diese Tatsachen etwas verschleieren, aber wie der Begriff “pseudoklassisch” schon andeutet, gibt es in JavaScript keine Klassen. Vererbung funktioniert über so genannte Prototypen. Dabei erben Objekte einfach Eigenschaften von anderen Objekten

Douglas Crockford hatte schon 2006 folgende Umsetzung der protoytpischen Vererbung vorgeschlagen:

function object(o) {
  function F() {}

  F.prototype = o;

  return new F();
}

Der Funktion object wird ein Objekt übergeben, und sie gibt wiederum ein neues, leeres Objekt zurück, das vom übergebenen Objekt erbt. Ähnlich wie eines der Muster für die pseudoklassische Vererbung, verwendet object intern einen temporären Konstruktor F um das neue Objekt zu erzeugen: return new F();. Der prototype-Eigenschaft von F wird dabei das übergebene Objekt zugewiesen, wodurch die Vererbung zustande kommt (Stichwort: Prototypen-Kette - siehe dazu die oben erwähnten Artikel).

Findet der JavaScript-Interpreter bei einem durch object erzeugten Objekt eine Eigenschaft nicht, dann arbeitet er die Prototypen-Kette ab, und wird (gegebenenfalls) beim ursprünglichen Objekt fündig.

Ein sehr simples Anwendungsbeispiel:

var parent = {
  name: 'Douglas',
  sayName: function () {
    return 'Ich heisse ' + this.name;
  },
};

var child = object(parent);

child.sayName(); // "Ich heisse Douglas"

Man kann child natürlich auch nach der Erzeugung noch Eigenschaften hinzufügen, z.B.

child.age = 30;

Peter Michaux hat eine noch etwas performantere Variante der object-Funktion vorgeschlagen, die eine Closure verwendet, wodurch der temporäre Konstruktor nur einmal erzeugt werden muss:

var object = (function () {
  function F() {}

  return function (o) {
    F.prototype = o;
    return new F();
  };
})();

In ECMAScript 5 braucht man sich nicht mehr selbst um die Umsetzung der prototypischen Vererbung zu kümmern, sondern bekommt mit Object.create die notwendige Funktionalität zur Verfügung gestellt:

var child = Object.create(parent);