Start · Sprachen · JavaScript · Referenz · Reflect.has()

Reflect.has()

Methode

Prüft, ob ein Objekt eine Eigenschaft besitzt, eigene oder geerbte. Funktioniert wie der <code>in</code>-Operator, aber als Funktion.

seit JavaScript ES2015 Kategorie: method-property

Signatur

Reflect.has(target, propertyKey)

Beschreibung

Reflect.has() ist die Funktionsform des in-Operators. Reflect.has(obj, "x") liefert dasselbe Ergebnis wie "x" in obj. Die Methode durchsucht dabei die ganze Prototyp-Kette. Sie findet also nicht nur eigene Eigenschaften, sondern auch geerbte.

Weil es eine echte Funktion ist, lässt sich Reflect.has() als Rückruffunktion übergeben, teilweise vorbelegen (z. B. mit bind) und in funktionalem Code verwenden. Vor allem ist sie das passende Gegenstück zur has-Falle eines Proxy. In einem eigenen has-Handler gibt man mit Reflect.has(target, key) an das Standardverhalten weiter.

Anders als in wirft Reflect.has() einen TypeError, wenn target kein Objekt ist. Werte wie "text" oder 42 werden nicht stillschweigend in Objekte umgewandelt. Beim in-Operator kommt es bei primitiven Werten ebenfalls zu einem Fehler, die Fehlermeldung ist dort aber weniger klar.

Parameter

Name Typ Default Beschreibung
$target Pflicht Object Das Objekt, in dem nach der Eigenschaft gesucht wird. Ist es kein Objekt, gibt es einen TypeError.
$propertyKey Pflicht string|symbol Name der gesuchten Eigenschaft. Andere Werte werden in einen String umgewandelt, z. B. 1 zu "1".

Beispiele

Grundlagen: eigene und geerbte Eigenschaften

const user = { name: 'Anna', role: 'admin' };

console.log(Reflect.has(user, 'name'));      // eigene Eigenschaft
console.log(Reflect.has(user, 'toString'));  // geerbt von Object.prototype
console.log(Reflect.has(user, 'email'));     // nicht vorhanden

// Gleiches Ergebnis wie der in-Operator
console.log('name' in user);
true true false true

Proxy: Eigenschaften mit Unterstrich verstecken

const config = { apiUrl: 'https://api.example.com', _secret: 'xyz' };

const safeConfig = new Proxy(config, {
  has(target, key) {
    if (typeof key === 'string' && key.startsWith('_')) {
      return false; // private Schlüssel verbergen
    }
    return Reflect.has(target, key); // Standardverhalten
  }
});

console.log('apiUrl' in safeConfig);
console.log('_secret' in safeConfig);
true false

Als Rückruffunktion: fehlende Pflichtfelder finden

const required = ['id', 'title', 'price'];
const product = { id: 7, title: 'Tastatur' };

const missing = required.filter((key) => !Reflect.has(product, key));
console.log(missing);
[ 'price' ]

Symbole und Fehler bei primitiven Werten

const tag = Symbol('tag');
const item = { [tag]: 'neu' };

console.log(Reflect.has(item, tag));

try {
  Reflect.has('Hallo', 'length');
} catch (err) {
  console.log(err instanceof TypeError);
}
true true

// Wichtig · Fallstricke

  • Geerbte Eigenschaften zählen mit: Reflect.has({}, 'toString') ist true. Wenn nur eigene Eigenschaften gemeint sind, ist Object.hasOwn() die richtige Wahl.
  • Vorhanden heißt nicht definiert: Eine Eigenschaft mit dem Wert undefined gilt trotzdem als vorhanden, das Ergebnis ist also true.
  • Kein Objekt als target: Primitive Werte wie Strings oder Zahlen führen zu einem TypeError. Bei unsicheren Eingaben vorher mit typeof x === 'object' && x !== null prüfen.
  • Proxy-Invarianten: Eine has-Falle darf eine Eigenschaft nicht verstecken, wenn sie am Zielobjekt nicht konfigurierbar ist oder das Zielobjekt nicht erweiterbar ist. Sonst wirft der Proxy einen TypeError.
  • with-Anweisung: Auch Namensabfragen innerhalb von with lösen die has-Falle aus, das kann unerwartet sein.
  • Kompatibilität: Läuft in allen modernen Browsern und ab Node.js 6. Der Internet Explorer unterstützt die Methode nicht.