Signatur
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
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));
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
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));
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
// Wichtig · Fallstricke
- Geerbte Eigenschaften ergeben immer
false. Das gilt auch dann, wennfor...insie durchläuft. Die Methode taugt also nicht, um vorherzusagen, wasfor...inausgibt. - Objekte ohne Prototyp (
Object.create(null)) und Objekte, die die Methode überschreiben, lassen einen direkten Aufruf fehlschlagen oder liefern falsche Ergebnisse. Robuster istObject.prototype.propertyIsEnumerable.call(obj, prop). - Wer das vollständige Attribut braucht, liest es über
Object.getOwnPropertyDescriptor(obj, prop)?.enumerableaus. 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
getOwnPropertyDescriptorausgelöst. - Die Methode wird in allen Browsern und in Node.js ohne Einschränkungen unterstützt.