Signatur
Beschreibung
Der instanceof-Operator prüft, ob die prototype-Eigenschaft eines Konstruktors irgendwo in der Prototype-Chain eines Objekts vorkommt. Der Rückgabewert ist ein boolescher Wert. Sein Verhalten kann mit Symbol.hasInstance angepasst werden.
Der instanceof-Operator prüft das Vorhandensein von constructor.prototype in der Prototype-Chain von object. Das bedeutet in der Regel (wenn auch nicht immer), dass object mit constructor erzeugt wurde.
Beachte, dass sich das Ergebnis eines instanceof-Tests ändern kann, wenn constructor.prototype nach der Erzeugung des Objekts neu zugewiesen wird (was normalerweise nicht empfohlen wird). Es kann sich auch ändern, wenn der Prototyp von object mit Object.setPrototypeOf geändert wird.
Classes verhalten sich auf dieselbe Weise, da Classes ebenfalls die prototype-Eigenschaft haben.
Bei bound functions sucht instanceof die prototype-Eigenschaft auf der Zielfunktion, da bound functions selbst kein prototype besitzen.
instanceof und Symbol.hasInstance
Wenn constructor eine Symbol.hasInstance-Methode hat, wird diese Methode vorrangig aufgerufen, mit object als einzigem Argument und constructor als this.
Da alle Funktionen standardmäßig von Function.prototype erben, legt meist die Methode Function.prototype[Symbol.hasInstance]() das Verhalten von instanceof fest, wenn die rechte Seite eine Funktion ist. Siehe die Seite Symbol.hasInstance für den genauen Algorithmus von instanceof.
instanceof und mehrere Realms
JavaScript-Ausführungsumgebungen (Windows, Frames usw.) befinden sich jeweils in ihrem eigenen Realm. Das bedeutet, dass sie unterschiedliche Built-ins haben (unterschiedliches globales Objekt, unterschiedliche Konstruktoren usw.). Das kann zu unerwarteten Ergebnissen führen. Zum Beispiel liefert [] instanceof window.frames[0].Array den Wert false, weil Array.prototype !== window.frames[0].Array.prototype und Arrays im aktuellen Realm von Ersterem erben.
Das mag zunächst nicht einleuchten, aber für Scripts, die mit mehreren Frames oder Fenstern arbeiten und Objekte über Funktionen von einem Kontext in einen anderen übergeben, ist das ein reales und ernstes Problem. Man kann zum Beispiel sicher prüfen, ob ein gegebenes Objekt tatsächlich ein Array ist, indem man Array.isArray() verwendet, unabhängig davon, aus welchem Realm es stammt.
Um beispielsweise zu prüfen, ob ein Node in einem anderen Kontext ein SVGElement ist, kann man myNode instanceof myNode.ownerDocument.defaultView.SVGElement verwenden.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $object Pflicht | any | — | Das zu prüfende Objekt. |
| $constructor Pflicht | Function | — | Konstruktor, gegen den geprüft werden soll. |
Rückgabewert
Beispiele
instanceof mit String verwenden
const literalString = "This is a literal string";
const stringObject = new String("String created with constructor");
literalString instanceof String; // false, string primitive is not a String
stringObject instanceof String; // true
literalString instanceof Object; // false, string primitive is not an Object
stringObject instanceof Object; // true
stringObject instanceof Date; // false
instanceof mit Map verwenden
const myMap = new Map();
myMap instanceof Map; // true
myMap instanceof Object; // true
myMap instanceof String; // false
Mit Object.create() erzeugte Objekte
function Shape() {}
function Rectangle() {
Shape.call(this); // call super constructor.
}
Rectangle.prototype = Object.create(Shape.prototype);
Rectangle.prototype.constructor = Rectangle;
const rect = new Rectangle();
rect instanceof Object; // true
rect instanceof Shape; // true
rect instanceof Rectangle; // true
rect instanceof String; // false
const literalObject = {};
const nullObject = Object.create(null);
nullObject.name = "My object";
literalObject instanceof Object; // true, every object literal has Object.prototype as prototype
({}) instanceof Object; // true, same case as above
nullObject instanceof Object; // false, prototype is end of prototype chain (null)
Zeigen, dass myCar vom Typ Car und vom Typ Object ist
function Car(make, model, year) {
this.make = make;
this.model = model;
this.year = year;
}
const myCar = new Car("Honda", "Accord", 1998);
const a = myCar instanceof Car; // returns true
const b = myCar instanceof Object; // returns true
Kein instanceof
if (!(myCar instanceof Car)) {
// Do something, like:
// myCar = new Car(myCar)
}
Falsche Schreibweise (unerreichbarer Code)
if (!myCar instanceof Car) {
// unreachable code
}
Verhalten von instanceof überschreiben
class C {
#value = "foo";
static getValue(x) {
return x.#value;
}
}
const x = { __proto__: C.prototype };
if (x instanceof C) {
console.log(C.getValue(x)); // TypeError: Cannot read private member #value from an object whose class did not declare it
}
Branded Check mit Symbol.hasInstance und in
class C {
#value = "foo";
static [Symbol.hasInstance](x) {
return #value in x;
}
static getValue(x) {
return x.#value;
}
}
const x = { __proto__: C.prototype };
if (x instanceof C) {
// Doesn't run, because x is not a C
console.log(C.getValue(x));
}
Verhalten auf die aktuelle Klasse beschränken
class C {
#value = "foo";
static [Symbol.hasInstance](x) {
return this === C && #value in x;
}
}
class D extends C {}
console.log(new C() instanceof D); // false
console.log(new C() instanceof C); // true
console.log({ __proto__: C.prototype } instanceof C); // false