Start · Sprachen · JavaScript · Referenz · Object.prototype.propertyIsEnumerable()

Object.prototype.propertyIsEnumerable()

Methode

Gibt <code>true</code> zurück, wenn die angegebene Eigenschaft eine <em>eigene</em> und <em>aufzählbare</em> Eigenschaft des Objekts ist, sonst <code>false</code>.

seit JavaScript ES3 (Baseline: alle Browser) Kategorie: method-property

Signatur

Object.prototype.propertyIsEnumerable(prop)

Beschreibung

propertyIsEnumerable() prüft zwei Bedingungen auf einmal: Die Eigenschaft muss direkt auf dem Objekt liegen, darf also nicht über die Prototypkette geerbt sein, und ihr Attribut enumerable muss true sein. Nur wenn beides zutrifft, liefert die Methode true.

Nützlich ist das, wenn man vorab wissen will, ob eine Eigenschaft bei Object.keys(), Object.entries(), JSON.stringify() oder im Spread-Operator {...obj} auftaucht. Das gilt für Zeichenketten-Schlüssel, denn Object.keys() und JSON.stringify() übergehen Symbole grundsätzlich. Eine for...in-Schleife durchläuft dagegen auch geerbte aufzählbare Eigenschaften. Die Methode beantwortet also nur, ob die Eigenschaft eine eigene aufzählbare ist, nicht, ob for...in sie erreicht.

Eigenschaften, die man per Zuweisung oder Objektliteral anlegt, sind standardmäßig aufzählbar. Mit Object.defineProperty() angelegte Eigenschaften sind es standardmäßig nicht. Eingebaute Methoden wie Array.prototype.map oder die Eigenschaft length von Arrays sind ebenfalls nicht aufzählbar.

Die Methode funktioniert auch mit Symbol-Schlüsseln. Nicht-Symbol-Argumente werden in Zeichenketten umgewandelt, deshalb ergeben arr.propertyIsEnumerable(0) und arr.propertyIsEnumerable("0") dasselbe.

Parameter

Name Typ Default Beschreibung
$prop Pflicht string | symbol Name der zu prüfenden Eigenschaft. Werte, die kein Symbol sind (z. B. Zahlen), werden in eine Zeichenkette umgewandelt.

Rückgabewert

Typ
boolean
Beschreibung
true, wenn die Eigenschaft direkt auf dem Objekt liegt und aufzählbar ist, sonst false. Auch für nicht vorhandene und geerbte Eigenschaften ergibt sich false.

Beispiele

Eigene, geerbte und nicht aufzählbare Eigenschaften unterscheiden

const user = { name: 'Anna' };
Object.defineProperty(user, 'id', { value: 42, enumerable: false });

console.log(user.propertyIsEnumerable('name'));     // eigene, aufzählbare Eigenschaft
console.log(user.propertyIsEnumerable('id'));       // eigene, aber nicht aufzählbar
console.log(user.propertyIsEnumerable('toString')); // geerbt vom Prototyp
console.log(user.propertyIsEnumerable('email'));    // gibt es nicht
console.log(Object.keys(user));
true false false false [ 'name' ]

Arrays: Indizes gegenüber length

const colors = ['rot', 'grün'];

console.log(colors.propertyIsEnumerable(0));        // Zahl wird zu '0'
console.log(colors.propertyIsEnumerable('1'));
console.log(colors.propertyIsEnumerable('length')); // eingebaut, nicht aufzählbar
console.log(colors.propertyIsEnumerable('map'));    // geerbt von Array.prototype
true true false false

Vorhersagen, was JSON.stringify ausgibt

class Session {
  #token = 'geheim';
  constructor(user) {
    this.user = user;
    // interne Eigenschaft absichtlich nicht aufzählbar
    Object.defineProperty(this, 'createdAt', { value: Date.now(), enumerable: false });
  }
}

const s = new Session('anna');
const serialisiert = ['user', 'createdAt'].filter((k) => s.propertyIsEnumerable(k));

console.log(serialisiert);
console.log(JSON.stringify(s));
[ 'user' ] {"user":"anna"}

Sicherer Aufruf bei Objekten ohne Prototyp

const dict = Object.create(null);
dict.key = 'wert';

// dict.propertyIsEnumerable('key') würde einen TypeError werfen
const isEnum = (obj, prop) => Object.prototype.propertyIsEnumerable.call(obj, prop);

console.log(isEnum(dict, 'key'));

const sym = Symbol('meta');
const obj = { [sym]: 1 };
console.log(isEnum(obj, sym)); // funktioniert auch mit Symbolen
true true

// Wichtig · Fallstricke

  • Geerbte Eigenschaften ergeben immer false. Das gilt auch dann, wenn for...in sie durchläuft. Die Methode taugt also nicht, um vorherzusagen, was for...in ausgibt.
  • Objekte ohne Prototyp (Object.create(null)) und Objekte, die die Methode überschreiben, lassen einen direkten Aufruf fehlschlagen oder liefern falsche Ergebnisse. Robuster ist Object.prototype.propertyIsEnumerable.call(obj, prop).
  • Wer das vollständige Attribut braucht, liest es über Object.getOwnPropertyDescriptor(obj, prop)?.enumerable aus. Dort lässt sich unterscheiden, ob die Eigenschaft fehlt (undefined) oder nicht aufzählbar ist (false).
  • Private Klassenfelder (#feld) sind keine Eigenschaften im herkömmlichen Sinn. Man kann sie mit dieser Methode nicht prüfen.
  • Bei Proxy-Objekten wird die Falle getOwnPropertyDescriptor ausgelöst.
  • Die Methode wird in allen Browsern und in Node.js ohne Einschränkungen unterstützt.