Signatur
Beschreibung
Function.prototype[Symbol.hasInstance]() ist die eingebaute Methode, die der Operator instanceof intern aufruft, wenn die rechte Seite eine Funktion ist und keine eigene Symbol.hasInstance-Methode hat. Der Ausdruck obj instanceof F wird also zu F[Symbol.hasInstance](obj) ausgewertet.
Das Standardverhalten entspricht dem Spezifikationsverfahren OrdinaryHasInstance: Ist this keine aufrufbare Funktion, ist das Ergebnis false. Bei gebundenen Funktionen (bind()) wird die Prüfung an die Zielfunktion weitergegeben. Andernfalls wird die Prototypkette von value durchlaufen und geprüft, ob this.prototype darin vorkommt. Primitive Werte ergeben immer false.
Praktisch nützlich ist die Methode vor allem, wenn man in einer eigenen static [Symbol.hasInstance]()-Implementierung auf das Standardverhalten zurückgreifen will. Ein direkter Aufruf wie Function.prototype[Symbol.hasInstance].call(F, obj) liefert außerdem immer die „echte“ Prototypketten-Prüfung, auch wenn F das Verhalten von instanceof überschrieben hat.
Die Eigenschaft ist nicht beschreibbar, nicht konfigurierbar und nicht aufzählbar. Deshalb lässt sie sich nicht per einfacher Zuweisung auf einer Funktion ersetzen. Stattdessen definiert man eine eigene Methode mit static in einer Klasse oder mit Object.defineProperty().
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $value Pflicht | any | Der zu prüfende Wert, also die linke Seite von instanceof. Bei primitiven Werten ist das Ergebnis immer false. |
Beispiele
Gleichwertigkeit mit instanceof
class Benutzer {}
const anna = new Benutzer();
console.log(anna instanceof Benutzer);
console.log(Benutzer[Symbol.hasInstance](anna));
console.log(Benutzer[Symbol.hasInstance]({}));
console.log(Benutzer[Symbol.hasInstance](42));
Eigenes instanceof mit Rückgriff auf das Standardverhalten
class Array2D {
static [Symbol.hasInstance](value) {
// Standardprüfung ODER „duck typing“ für verschachtelte Arrays
if (Function.prototype[Symbol.hasInstance].call(this, value)) return true;
return Array.isArray(value) && value.every(Array.isArray);
}
}
console.log(new Array2D() instanceof Array2D);
console.log([[1, 2], [3, 4]] instanceof Array2D);
console.log([1, 2] instanceof Array2D);
Überschriebenes instanceof umgehen
class Immer {
static [Symbol.hasInstance]() {
return true; // lügt bei jedem Wert
}
}
const obj = {};
console.log(obj instanceof Immer);
// Echte Prototypketten-Prüfung erzwingen:
console.log(Function.prototype[Symbol.hasInstance].call(Immer, obj));
Gebundene Funktionen und Nicht-Funktionen
function Punkt(x, y) { this.x = x; this.y = y; }
const GebundenerPunkt = Punkt.bind(null, 0);
const p = new Punkt(1, 2);
console.log(GebundenerPunkt[Symbol.hasInstance](p));
// this ist keine Funktion -> false statt Fehler
console.log(Function.prototype[Symbol.hasInstance].call({}, p));
// Wichtig · Fallstricke
- Nicht beschreibbar:
F[Symbol.hasInstance] = ...hat keine Wirkung, im Strict Mode wird einTypeErrorausgelöst, weil die geerbte Eigenschaft nicht beschreibbar ist. Eigene Logik definiert man mitstatic [Symbol.hasInstance]()oderObject.defineProperty(). - Unterschied zu
instanceof: Wird die Methode direkt mit einemthisaufgerufen, das keine Funktion ist, gibt siefalsezurück.instanceofmit einer rechten Seite, die kein Objekt oder nicht aufrufbar ist, löst dagegen einenTypeErroraus. - Ist
F.prototypekein Objekt (z. B. nachträglich aufnullgesetzt), löst die Prüfung bei einem Objekt alsvalueeinenTypeErroraus. - Realms: Objekte aus einem anderen
iframeodervm-Kontext haben andere Prototypen.[] instanceof Arraykann dortfalseergeben. Für Arrays deshalbArray.isArray()verwenden. - Die Prototypkette ist veränderbar (
Object.setPrototypeOf()).instanceofist daher kein sicherer Typnachweis. - Kompatibilität: ES2015, in allen modernen Browsern und in Node.js 6.5+ verfügbar, nicht im Internet Explorer.