JavaScript/Objekte/Object/isPrototypeOf
Unter Verwendung der Methode isPrototypeOf kann überprüft werden, ob ein Objekt Teil der Prototypenkette eines anderen Objektes ist, es also gegebenenfalls Eigenschaften und Methoden von diesem Objekt erbt.
Syntax
Object.prototype.isPrototypeOf(object)
Writable | true |
Enumerable | false |
Configurable | true |
Prototyp
Eigenschaften
Inhaltsverzeichnis
Beschreibung
Die von Object.prototype vererbte Methode isPrototypeOf erwartet als Parameter ein Objekt, dessen Prototypenkette nach dem Objekt durchsucht werden soll, auf dem die Methode aufgerufen wurde. War die Suche erfolgreich, dann wird von der Methode der boolesche Wert true zurückgegeben, sonst der Wert false.
const parent = { };
const child = Object.create(parent);
console.log(parent.isPrototypeOf(child)); // true
In diesem Beispiel wird zunächst in Literalschreibweise (Object Initializer) ein neues Objekt ohne Eigenschaften erstellt und der Konstante mit dem Bezeichner parent als Wert zugewiesen. Danach wird die Methode Object.create aufgerufen, wobei eine Referenz auf das zuvor erstellte Objekt als Argument übergeben wird. Der in der Konstante mit dem Bezeichner child gespeicherte Rückgabewert dieses Methodenaufrufs ist nun ein neues Objekt, dessen Prototyp, also der Wert der internen Eigenschaft [[Prototype]], das Objekt mit dem Bezeichner parent ist.
Schließlich wird die Methode isPrototypeOf auf dem Objekt parent aufgerufen und dabei eine Referenz auf das Objekt child als Argument übergeben. Es wird also geprüft, ob das Objekt parent teil der Prototypenkette des Objektes child ist. Dies ist hier der Fall, sodass im Ergebnis der Wert true in die Konsole geschrieben wird.
const array = [ ];
console.log(Object.prototype.isPrototypeOf(array)); // true
console.log(Array.prototype.isPrototypeOf(array)); // true
Es wird durch die Methode isPrototypeOf jedoch nicht nur geprüft, ob das Objekt, auf dem die Methode aufgerufen wurde, der direkte Vorfahr des als Argument übergebenen Objektes ist, wie es im ersten Beispiel der Fall war, sondern es wird prinzipiell die ganze Prototypenkette des zu prüfenden Objektes durchsucht, solange bis eine Übereinstimmung gefunden wurde oder die Kette an einer Stelle bei dem Wert null endet.
So wird in dem Beispiel oben zunächst in Literalschreibweise (Array Initializer) ein Array erzeugt und in einer Konstanten gespeichert. Dieses Arrayobjekt wird dann im Folgenden bei zwei Aufrufen an die Methode isPrototypeOf übergeben, wobei die Methode einmal auf dem Objekt Object.prototype und einmal auf dem Objekt Array.prototype aufgerufen wird. Da Array.prototype der direkte Vorfahr, also der Wert der internen Eigenschaft [[Prototype]] des Arrays ist, wird hier wenig überraschend true zurückgegeben. Die Prüfung auf das Objekt Object.prototype ergibt jedoch ebenfalls true, da dieses Objekt der Prototyp von Array.prototype ist, es sich demnach ebenfalls in der Prototypenkette der Arrayinstanz befindet.
Abgrenzung zu instanceof
Die Methode isPrototypeOf unterscheidet sich vom Operator instanceof trotz ähnlicher Funktionalität in einem wesentlichen Punkt. Während die Methode isPrototypeOf nämlich daraufhin testet, ob ein Objekt selbst Prototyp eines anderen Objektes ist, prüft der Operator instanceof, ob es sich bei der als zweiten Operanden übergebenen Funktion um einen Konstruktor handelt, dessen prototypisches Objekt ein Prototyp des Objektes ist, das als erster Operand notiert wurde. Es wird hier also gegen einen Konstruktor getestet und nicht gegen einen Prototypen.
const object = { };
console.log(Object.prototype.isPrototypeOf(object)); // true
console.log(object instanceof Object); // true
In diesem Beispiel wird zunächst durch ein Objektliteral ein planes Objekt erzeugt. Wird nun die Methode isPrototypeOf auf Object.prototype aufgerufen und dabei eine Referenz auf das zuvor erzeugte Objekt übergeben, dann wird der Wert true zurückgegeben, da Object.prototype der Prototyp dieses Objektes ist. Mit dem Operator instanceof wird nun getestet, ob das zuvor erzeugte Objekt eine Instanz des Konstruktors Object ist und diese Prüfung ergibt ebenfalls den Wert true, da das prototypische Objekt des Konstruktors Object, also Object.prototype, der Prototyp des Instanzobjektes ist.
const object = { };
console.log(object instanceof Object.prototype); // Type Error
Würde dem Operator instanceof als zweiter Operand jedoch nicht wie im letzten Beispiel ein Konstruktor übergeben sondern ein prototypisches Objekt, dann würde hierdurch ein Typfehler produziert, da es sich bei Objekten wie zum Beispiel Object.prototype in aller Regel nicht um Funktionen handelt. Will man also wissen, ob ein Objekt ein Prototyp eines anderen Objektes ist, dann ist die Methode isPrototypeOf zu verwenden. Soll hingegen geprüft werden, ob ein Objekt eine Instanz eines bestimmten Konstruktors ist, dann kann dies mit dem Operator instanceof bewerkstelligt werden.
Eigene Eigenschaften
Das Funktionsobjekt isPrototypeOf verfügt über zwei eigene Eigenschaften mit den Namen length und name. Die Eigenschaft length hat den Wert 1
, denn dies entspricht der Anzahl der Parameter der Funktion. Die Eigenschaft name gibt den Namen der Methode zurück, also den String isPrototypeOf. Beide Eigenschaften sind schreibgeschützt, können aber durch Definition, etwa unter Verwendung der Methode defineProperty verändert werden. Aber abgesehen davon, dass eine Änderung der Werte der beiden Eigenschaften kaum sinnvoll wäre, ist auch grundsätzlich davon abzuraten, denn abgesehen von der Bereitstellung von Polyfills, sollten eingebaute Objekte prinzipiell nicht verändert werden.
Weblinks
- ECMAScript 2017 (7th Edition, ECMA-262 Draft): Object.prototype.isPrototypeOf
- ECMAScript 2015 (6th Edition, ECMA-262): Object.prototype.isPrototypeOf