Start · Sprachen · JavaScript · Referenz · Object.prototype.__proto__

Object.prototype.__proto__

Eigenschaft

Accessor-Eigenschaft, die das interne <code>[[Prototype]]</code> eines Objekts (ein Objekt oder <code>null</code>) liest bzw. setzt. Veraltet – besser <code>Object.getPrototypeOf()</code> nutzen.

seit JavaScript ES2015 (Annex B, standardisiert als Legacy-Feature deprecated seit ja Kategorie: method-property

Signatur

get/set Object.prototype.__proto__

Beschreibung

Die Eigenschaft __proto__ ist ein Getter/Setter-Paar auf Object.prototype. Der Getter liefert den Prototyp eines Objekts, also das Objekt, von dem es Eigenschaften und Methoden erbt. Der Setter ändert diesen Prototyp nachträglich. Intern entspricht das Lesen Object.getPrototypeOf(this) und das Schreiben Object.setPrototypeOf(this, wert).

Ursprünglich eine nicht standardisierte Browser-Erweiterung, wurde __proto__ in ES2015 nur aus Kompatibilitätsgründen in Anhang B (Legacy-Features für Webbrowser) aufgenommen. Für neuen Code sollte man stattdessen Object.getPrototypeOf(), Object.setPrototypeOf() und Object.create() verwenden.

Wichtig: Die Accessor-Eigenschaft funktioniert nur bei Objekten, die (direkt oder indirekt) von Object.prototype erben. Objekte mit Object.create(null) besitzen kein __proto__. Davon zu unterscheiden ist die Objektliteral-Syntax { __proto__: proto }: Sie ist regulär standardisiert, nicht veraltet und setzt den Prototyp direkt beim Erzeugen – auch ohne Abhängigkeit von Object.prototype.

Wird dem Setter ein Wert zugewiesen, der weder Objekt noch null ist, passiert stillschweigend nichts. Bei nicht erweiterbaren Objekten (Object.preventExtensions()) oder bei zyklischen Prototyp-Ketten wird ein TypeError geworfen.

Parameter

Name Typ Default Beschreibung
$value Object | null Nur beim Setzen: der neue Prototyp. Andere Werte (z. B. Zahlen, Strings) werden ignoriert, ohne Fehler.

Rückgabewert

Typ
Object | null
Beschreibung
Beim Lesen: das [[Prototype]] des Objekts bzw. null am Ende der Prototyp-Kette. Beim Setzen: undefined (die Zuweisung selbst ergibt den zugewiesenen Wert).

Beispiele

Prototyp lesen

class Tier {}
class Hund extends Tier {}
const bello = new Hund();

console.log(bello.__proto__ === Hund.prototype);
console.log(bello.__proto__.__proto__ === Tier.prototype);
console.log(Object.prototype.__proto__);
// Moderne Alternative:
console.log(Object.getPrototypeOf(bello) === Hund.prototype);
true true null true

Prototyp nachträglich setzen (veraltet) vs. moderne Alternativen

const basis = {
  gruss() { return `Hallo, ${this.name}!`; }
};

const nutzer = { name: 'Anna' };
nutzer.__proto__ = basis;          // Legacy-Setter
console.log(nutzer.gruss());

// Besser:
const nutzer2 = Object.create(basis, { name: { value: 'Ben' } });
console.log(nutzer2.gruss());

// Objektliteral-Syntax (standardisiert, nicht veraltet):
const nutzer3 = { __proto__: basis, name: 'Cem' };
console.log(nutzer3.gruss());
Hallo, Anna! Hallo, Ben! Hallo, Cem!

Objekte ohne Object.prototype

const dict = Object.create(null);
console.log(dict.__proto__);           // kein Accessor vorhanden

dict.__proto__ = { x: 1 };             // wird zur normalen Eigenschaft
console.log(Object.keys(dict));
console.log(Object.getPrototypeOf(dict));
undefined [ '__proto__' ] null

Ungültige Werte und Fehlerfälle

const obj = {};
obj.__proto__ = 42;                    // wird ignoriert
console.log(Object.getPrototypeOf(obj) === Object.prototype);

const a = {};
const b = { __proto__: a };
try {
  a.__proto__ = b;                     // Zyklus
} catch (e) {
  console.log(e instanceof TypeError);
}
true true

// Wichtig · Fallstricke

  • Veraltet: Der Accessor Object.prototype.__proto__ ist nur als Legacy-Feature (Annex B) standardisiert. Deno und manche gehärteten Umgebungen (z. B. Node.js mit --disable-proto) stellen ihn nicht bereit. Nutze Object.getPrototypeOf()/Object.setPrototypeOf().
  • Performance: Das nachträgliche Ändern des Prototyps macht Optimierungen der JavaScript-Engines zunichte und kann Code deutlich verlangsamen – auch Code, der das Objekt später nur liest. Prototyp besser beim Erzeugen festlegen (Object.create() oder { __proto__: … }).
  • Sicherheit – Prototype Pollution: Werden Schlüssel aus unkontrollierten Daten (z. B. JSON.parse-Ergebnissen, Query-Strings) rekursiv in Objekte gemischt, kann ein Schlüssel "__proto__" Object.prototype manipulieren und alle Objekte der Anwendung beeinflussen. Gegenmaßnahmen: Schlüssel __proto__, constructor und prototype filtern, Object.create(null) oder Map als Wörterbuch verwenden, ggf. Object.freeze(Object.prototype).
  • JSON.parse('{"__proto__": {}}') erzeugt eine eigene Eigenschaft namens __proto__, setzt aber keinen Prototyp; erst das anschließende Kopieren per Zuweisung ist gefährlich.
  • Berechnete Schlüssel ({ ["__proto__"]: x }) und Kurzschreibweise ({ __proto__ }) setzen im Objektliteral keinen Prototyp, sondern legen eine normale Eigenschaft an.