Was sind Prototypenketten in JavaScript?

Februar 16, 2025

In JavaScript können Funktionen Eigenschaften haben. Jede Funktion besitzt eine spezielle Eigenschaft namens prototype.

function doSomething() {} 
console.log(doSomething.prototype); 
// Funktionen in JavaScript haben immer eine Standard-Prototype-Eigenschaft
// Ausnahme: Pfeilfunktionen haben keine Standard-Prototype-Eigenschaft
const doSomethingFromArrowFunction = () => {}; 
console.log(doSomethingFromArrowFunction.prototype); 

doSomething() hat eine Standard-prototype-Eigenschaft. Nach Ausführung des obigen Codes zeigt die Konsole ein Objekt ähnlich dem folgenden an:

{ constructor: ƒ doSomething(), [[Prototype]]: { constructor: ƒ Object(), hasOwnProperty: ƒ hasOwnProperty(), isPrototypeOf: ƒ isPrototypeOf(), propertyIsEnumerable: ƒ propertyIsEnumerable(), toLocaleString: ƒ toLocaleString(), toString: ƒ toString(), valueOf: ƒ valueOf() } } 

Hinweis: Die Chrome-Konsole verwendet [[Prototype]], um den Prototyp des Objekts gemäß der Spezifikation darzustellen; Firefox verwendet .prototype. Der Einheitlichkeit halber verwenden wir [[Prototype]].

Wir können dem Prototyp von doSomething() Eigenschaften hinzufügen:

function doSomething() {} 
doSomething.prototype.foo = "bar"; 
console.log(doSomething.prototype); 

Ergebnis:

{ foo: "bar", constructor: ƒ doSomething(), [[Prototype]]: { constructor: ƒ Object(), hasOwnProperty: ƒ hasOwnProperty(), isPrototypeOf: ƒ isPrototypeOf(), propertyIsEnumerable: ƒ propertyIsEnumerable(), toLocaleString: ƒ toLocaleString(), toString: ƒ toString(), valueOf: ƒ valueOf() } } 

Mit dem Operator new kann eine Instanz von doSomething() basierend auf diesem Prototyp erstellt werden. Der Aufruf der Funktion mit dem Operator new gibt ein Objekt zurück, das eine Instanz der Funktion ist. Diesem Objekt können dann Eigenschaften hinzugefügt werden.

function doSomething() {} 
doSomething.prototype.foo = "bar"; // Eigenschaft zum Prototyp hinzufügen
const doSomeInstancing = new doSomething(); 
doSomeInstancing.prop = "some value"; // Eigenschaft zum Objekt hinzufügen
console.log(doSomeInstancing); 

Ergebnis:

{ prop: "some value", [[Prototype]]: { foo: "bar", constructor: ƒ doSomething(), [[Prototype]]: { constructor: ƒ Object(), hasOwnProperty: ƒ hasOwnProperty(), isPrototypeOf: ƒ isPrototypeOf(), propertyIsEnumerable: ƒ propertyIsEnumerable(), toLocaleString: ƒ toLocaleString(), toString: ƒ toString(), valueOf: ƒ valueOf() } } } 

[[Prototype]] von doSomeInstancing ist doSomething.prototype. Beim Zugriff auf eine Eigenschaft von doSomeInstancing prüft die Runtime zunächst, ob doSomeInstancing diese Eigenschaft besitzt.

Falls nicht, sucht die Runtime die Eigenschaft in doSomeInstancing.[[Prototype]] (also doSomething.prototype). Wenn doSomeInstancing.[[Prototype]] die gesuchte Eigenschaft hat, wird diese Eigenschaft verwendet.

Andernfalls wird doSomeInstancing.[[Prototype]].[[Prototype]] geprüft. Standardmäßig ist [[Prototype]] der prototype-Eigenschaft jeder Funktion Object.prototype. Daher wird doSomeInstancing.[[Prototype]].[[Prototype]] (also doSomething.prototype.[[Prototype]] oder Object.prototype) durchsucht. Dieser Vorgang wird als Prototypenkette bezeichnet.

Wenn die Eigenschaft nicht in doSomeInstancing.[[Prototype]].[[Prototype]] gefunden wird, wird doSomeInstancing.[[Prototype]].[[Prototype]].[[Prototype]] durchsucht. Allerdings existiert doSomeInstancing.[[Prototype]].[[Prototype]].[[Prototype]] nicht, da Object.prototype.[[Prototype]] null ist. Nachdem die gesamte Prototypenkette durchsucht wurde, stellt die Runtime fest, dass die Eigenschaft nicht existiert und der Wert der Eigenschaft undefined ist.

function doSomething() {} 
doSomething.prototype.foo = "bar"; 
const doSomeInstancing = new doSomething(); 
doSomeInstancing.prop = "some value"; 
console.log("doSomeInstancing.prop: ", doSomeInstancing.prop); 
console.log("doSomeInstancing.foo: ", doSomeInstancing.foo); 
console.log("doSomething.prop: ", doSomething.prop); 
console.log("doSomething.foo: ", doSomething.foo); 
console.log("doSomething.prototype.prop:", doSomething.prototype.prop); 
console.log("doSomething.prototype.foo: ", doSomething.prototype.foo); 

Ergebnis:


doSomeInstancing.prop: some value
doSomeInstancing.foo: bar
doSomething.prop: undefined
doSomething.foo: undefined
doSomething.prototype.prop: undefined
doSomething.prototype.foo: bar

Leave A Comment

Kategorien

Recent Posts

Create your account