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

Reflect.ownKeys()

Methode

Gibt ein Array aller eigenen Eigenschaftsschlüssel eines Objekts zurück: Strings und Symbole, aufzählbar oder nicht.

seit JavaScript ES2015 Kategorie: method-property

Signatur

Reflect.ownKeys(target)

Beschreibung

Reflect.ownKeys() liefert alle eigenen Schlüssel eines Objekts. Dazu gehören String-Schlüssel und Symbol-Schlüssel, aufzählbare und nicht aufzählbare. Das Ergebnis entspricht Object.getOwnPropertyNames(target).concat(Object.getOwnPropertySymbols(target)). Geerbte Eigenschaften aus der Prototypkette sind nicht enthalten.

Die Reihenfolge ist festgelegt: Zuerst kommen ganzzahlige Index-Schlüssel in aufsteigender Reihenfolge. Danach folgen die übrigen String-Schlüssel in der Reihenfolge, in der sie angelegt wurden. Zum Schluss kommen die Symbole, ebenfalls in Anlagereihenfolge.

Typische Einsatzfälle:

  • vollständiges Kopieren oder Klonen von Objekten samt Symbolen und nicht aufzählbaren Eigenschaften, etwa zusammen mit Object.getOwnPropertyDescriptor()
  • Untersuchen von Objekten beim Debuggen oder Serialisieren
  • Weiterreichen an den Ziel-Handler im ownKeys-Trap eines Proxy

Ist target kein Objekt, wirft die Methode einen TypeError. Object.keys() verhält sich anders: Es wandelt Primitive in Objekte um.

Parameter

Name Typ Default Beschreibung
$target Pflicht object Das Objekt, dessen eigene Schlüssel ermittelt werden sollen. Primitive Werte führen zu einem TypeError.

Rückgabewert

Typ
Array<string | symbol>
Beschreibung
Ein neues Array mit allen eigenen Eigenschaftsschlüsseln von target, in der oben beschriebenen Reihenfolge.

Beispiele

Alle Schlüssel inklusive Symbol und nicht aufzählbarer Eigenschaft

const id = Symbol('id');
const user = { name: 'Anna', 2: 'b', 1: 'a', [id]: 42 };
Object.defineProperty(user, 'secret', { value: 'x', enumerable: false });

console.log(Object.keys(user));
console.log(Reflect.ownKeys(user));
[ '1', '2', 'name' ] [ '1', '2', 'name', 'secret', Symbol(id) ]

Vollständige flache Kopie mit Property-Deskriptoren

const cloneExact = (obj) => {
  const copy = Object.create(Object.getPrototypeOf(obj));
  for (const key of Reflect.ownKeys(obj)) {
    Object.defineProperty(copy, key, Object.getOwnPropertyDescriptor(obj, key));
  }
  return copy;
};

const tag = Symbol('tag');
const original = { get full() { return 'Getter bleibt erhalten'; }, [tag]: 'intern' };
const kopie = cloneExact(original);
console.log(kopie.full, kopie[tag]);
Getter bleibt erhalten intern

Private Felder im Proxy per ownKeys-Trap ausblenden

const data = { _token: 'abc', user: 'max', role: 'admin' };

const safe = new Proxy(data, {
  ownKeys: (target) =>
    Reflect.ownKeys(target).filter((k) => typeof k !== 'string' || !k.startsWith('_'))
});

console.log(Reflect.ownKeys(safe));
console.log(Object.keys(safe));
[ 'user', 'role' ] [ 'user', 'role' ]

Arrays und Fehler bei Primitiven

console.log(Reflect.ownKeys(['a', 'b']));

try {
  Reflect.ownKeys('text');
} catch (err) {
  console.log(err.constructor.name);
}
[ '0', '1', 'length' ] TypeError

// Wichtig · Fallstricke

  • TypeError bei Primitiven: Reflect.ownKeys(42) oder Reflect.ownKeys(null) wirft einen Fehler. Object.getOwnPropertyNames('abc') dagegen funktioniert, weil es Primitive vorher in Objekte umwandelt.
  • Keine geerbten Schlüssel: Eigenschaften aus der Prototypkette tauchen nicht auf, zum Beispiel Methoden einer Klasse bei deren Instanzen. Für diese Fälle muss man mit Object.getPrototypeOf() die Kette selbst durchlaufen.
  • Nicht aufzählbare Schlüssel: Auch Einträge wie length bei Arrays werden zurückgegeben. Wer nur aufzählbare Schlüssel braucht, filtert mit Object.prototype.propertyIsEnumerable oder nutzt Object.keys().
  • Invarianten im Proxy: Ein ownKeys-Trap darf nicht konfigurierbare Schlüssel des Ziels nicht weglassen. Bei nicht erweiterbaren Zielen darf er keine zusätzlichen Schlüssel erfinden. Sonst wirft die Engine einen TypeError. Außerdem sind nur Strings und Symbole als Rückgabe erlaubt.
  • Kompatibilität: Unterstützt in allen modernen Browsern und in Node.js ab Version 6. Im Internet Explorer fehlt die Methode.