Start · Sprachen · JavaScript · Referenz · Function.prototype[Symbol.hasInstance]()

Function.prototype[Symbol.hasInstance]()

Methode

Legt das Standardverfahren fest, mit dem <code>instanceof</code> prüft, ob ein Wert eine Instanz einer Konstruktorfunktion ist (Prototypkette gegen <code>F.prototype</code>).

seit JavaScript ES2015 Kategorie: method-property

Signatur

Function.prototype[Symbol.hasInstance](value)

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));
true true false false

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);
true true false

Ü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));
true false

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));
true false

// Wichtig · Fallstricke

  • Nicht beschreibbar: F[Symbol.hasInstance] = ... hat keine Wirkung, im Strict Mode wird ein TypeError ausgelöst, weil die geerbte Eigenschaft nicht beschreibbar ist. Eigene Logik definiert man mit static [Symbol.hasInstance]() oder Object.defineProperty().
  • Unterschied zu instanceof: Wird die Methode direkt mit einem this aufgerufen, das keine Funktion ist, gibt sie false zurück. instanceof mit einer rechten Seite, die kein Objekt oder nicht aufrufbar ist, löst dagegen einen TypeError aus.
  • Ist F.prototype kein Objekt (z. B. nachträglich auf null gesetzt), löst die Prüfung bei einem Objekt als value einen TypeError aus.
  • Realms: Objekte aus einem anderen iframe oder vm-Kontext haben andere Prototypen. [] instanceof Array kann dort false ergeben. Für Arrays deshalb Array.isArray() verwenden.
  • Die Prototypkette ist veränderbar (Object.setPrototypeOf()). instanceof ist daher kein sicherer Typnachweis.
  • Kompatibilität: ES2015, in allen modernen Browsern und in Node.js 6.5+ verfügbar, nicht im Internet Explorer.