Prototypes

Geschätzte Lektüre: 7 Minuten 542 Ansichten

rototypes sind ein grundlegendes Konzept in JavaScript, das die prototypenbasierte Vererbung ermöglicht. Im Gegensatz zu klassischen Vererbungsmodellen (wie in Java oder C++) verwendet JavaScript Prototypen, um Eigenschaften und Methoden zwischen Objekten zu teilen.

Grundlagen von Prototypen

Was ist ein Prototype?

Jedes JavaScript-Objekt hat eine versteckte Eigenschaft [[Prototype]] (oft als __proto__ zugänglich), die auf ein anderes Objekt verweist oder null. Wenn Sie auf eine Eigenschaft oder Methode eines Objekts zugreifen und diese nicht direkt auf dem Objekt gefunden wird, sucht JavaScript automatisch im Prototypen des Objekts, dann im Prototypen des Prototypen usw. – dies wird „Prototypenkette“ genannt.

Der prototype-Property von Funktionen

Konstruktorfunktionen haben eine spezielle Eigenschaft prototype. Wenn Sie eine Funktion mit new aufrufen, wird das [[Prototype]] des neu erstellten Objekts auf das prototype-Objekt der Konstruktorfunktion gesetzt.

function Person(name) {
  this.name = name;
}

// Hinzufügen einer Methode zum Prototype
Person.prototype.greet = function() {
  console.log(`Hallo, mein Name ist ${this.name}`);
};

const max = new Person('Max');
max.greet(); // "Hallo, mein Name ist Max"

Prototypenkette

Die Prototypenkette ist der Mechanismus, durch den JavaScript Vererbung implementiert:

function Person(name) {
  this.name = name;
}

Person.prototype.greet = function() {
  console.log(`Hallo, ich bin ${this.name}`);
};

function Student(name, subject) {
  Person.call(this, name);
  this.subject = subject;
}

// Vererbung der Prototype-Eigenschaften
Student.prototype = Object.create(Person.prototype);
Student.prototype.constructor = Student;

Student.prototype.study = function() {
  console.log(`${this.name} studiert ${this.subject}`);
};

const student = new Student('Anna', 'Informatik');
student.greet(); // Von Person.prototype
student.study(); // Von Student.prototype

Wichtige Methoden im Zusammenhang mit Prototypen

Object.getPrototypeOf(obj)

Gibt den Prototypen eines Objekts zurück:

const arr = [];
console.log(Object.getPrototypeOf(arr) === Array.prototype); // true

Object.setPrototypeOf(obj, prototype)

Setzt den Prototypen eines Objekts (sollte sparsam verwendet werden):

const obj = {};
const prototype = { greet: () => console.log("Hallo!") };
Object.setPrototypeOf(obj, prototype);
obj.greet(); // "Hallo!"

Object.create(proto)

Erstellt ein neues Objekt mit dem angegebenen Prototypen:

const personPrototype = {
  greet() {
    console.log(`Hallo, ich bin ${this.name}`);
  }
};

const person = Object.create(personPrototype);
person.name = 'Klaus';
person.greet(); // "Hallo, ich bin Klaus"

instanceof Operator

Überprüft, ob ein Objekt in der Prototypenkette einer Konstruktorfunktion vorkommt:

console.log([] instanceof Array); // true
console.log([] instanceof Object); // true
console.log({} instanceof Array); // false

Unterschied zwischen __proto__ und prototype

  • prototype ist eine Eigenschaft von Funktionen (genauer: von Konstruktorfunktionen) und definiert, was allen Instanzen dieser Funktion als Prototyp zugewiesen wird.
  • __proto__ ist eine Eigenschaft von Objekten, die auf ihren Prototypen verweist (veraltet, sollte durch Object.getPrototypeOf() ersetzt werden).
function Foo() {}
const foo = new Foo();

console.log(foo.__proto__ === Foo.prototype); // true
console.log(Object.getPrototypeOf(foo) === Foo.prototype); // true

Prototypen bei eingebauten Objekten

Auch eingebaute JavaScript-Objekte wie Arrays oder Strings verwenden Prototypen:

const arr = [1, 2, 3];
// Die Array-Methoden sind im Array.prototype definiert
console.log(arr.map === Array.prototype.map); // true

const str = "Hallo";
// String-Methoden sind in String.prototype
console.log(str.toUpperCase === String.prototype.toUpperCase); // true

Eigenschaften überschatten

Wenn eine Eigenschaft sowohl im Objekt selbst als auch im Prototypen existiert, wird die „nähere“ Eigenschaft verwendet:

const parent = { value: 10 };
const child = { value: 20 };

Object.setPrototypeOf(child, parent);

console.log(child.value); // 20 (von child)
delete child.value;
console.log(child.value); // 10 (von parent)

Moderne Klassen vs. Prototypen

ES6-Klassen sind syntaktischer Zucker über dem Prototypensystem:

class Person {
  constructor(name) {
    this.name = name;
  }
  
  greet() {
    console.log(`Hallo, ich bin ${this.name}`);
  }
}

// Ist äquivalent zu:
function Person(name) {
  this.name = name;
}
Person.prototype.greet = function() {
  console.log(`Hallo, ich bin ${this.name}`);
};

Performance-Überlegungen

  • Das Ändern von Prototypen zur Laufzeit (insbesondere von eingebauten Prototypen) kann die Performance beeinträchtigen.
  • Lange Prototypenketten können den Property-Zugriff verlangsamen.
  • Object.create(null) erstellt ein Objekt ohne Prototypen, was für reine Datencontainer nützlich sein kann.

Wichtiges Konzept

JavaScript-Prototypen sind ein wichtiges Konzept, das:

  • Objektvererbung ermöglicht
  • Methoden- und Eigenschaftsteilung zwischen Objekten erlaubt
  • Die Grundlage für das Klassen-System in ES6 bildet
  • Flexiblere Vererbungsmuster als klassische Vererbung ermöglicht

Das Verständnis von Prototypen ist entscheidend, um JavaScripts Objektmodell und Vererbungsmechanismen vollständig zu begreifen.

Dieses Dokument teilen

Prototypes

Oder Link kopieren

INHALT

Abonnieren

×
Cancel