W3docs

JavaScript Property Descriptors

Erfahren Sie, wie JavaScript Property Flags (writable, enumerable, configurable) und Deskriptoren funktionieren, einschließlich defineProperty, freeze, seal und Strict-Mode-Verhalten.

JavaScript Property Flags und Deskriptoren bieten präzise Kontrolle über object-Eigenschaften und ermöglichen eine robuste und sichere Anwendungsentwicklung. Dieser Artikel beleuchtet diese Features im Detail und liefert praktische Einblicke sowie Code-Beispiele, die Ihnen helfen, das Verhalten von Eigenschaften effektiv zu steuern.

JavaScript Property Attributes verstehen

JavaScript objects sind Sammlungen von Eigenschaften, und jede Eigenschaft besitzt zugehörige Attribute, die ihr Verhalten definieren. Diese Attribute, häufig als Property Flags bezeichnet, umfassen:

  • Writable: Legt fest, ob der Wert der Eigenschaft geändert werden kann.
  • Enumerable: Steuert, ob die Eigenschaft bei der Aufzählung sichtbar ist, beispielsweise in einer for...in-Schleife.
  • Configurable: Gibt an, ob die Eigenschaft gelöscht oder geändert werden kann.

Diese Flags sind entscheidend, um den Zugriff auf object-Eigenschaften zu kontrollieren, die Datenintegrität sicherzustellen und Kapselung in JavaScript-Anwendungen umzusetzen.

Property Descriptors im Detail

Property Descriptors liefern detaillierte Informationen über die Eigenschaft eines object und kapseln deren Wert und Flags. Sie werden mit Object.getOwnPropertyDescriptor(obj, propName) abgerufen und mit Object.defineProperty(obj, propName, descriptor) gesetzt. Ein Property Descriptor-object kann folgende Felder enthalten:

  • value: Der der Eigenschaft zugeordnete Wert.
  • writable: Gibt an, ob der Eigenschaftswert geändert werden kann.
  • enumerable: Zeigt an, ob die Eigenschaft aufzählbar ist.
  • configurable: Bestimmt, ob der Property Descriptor geändert und die Eigenschaft aus dem object gelöscht werden kann.

Hinweis: Wenn Sie eine Eigenschaft auf normalem Weg anlegen (user.name = "John"), werden alle drei Flags auf true gesetzt. Wird eine neue Eigenschaft jedoch über Object.defineProperty definiert, ist jedes nicht angegebene Flag standardmäßig false.


javascript— editable

Object.getOwnPropertyDescriptor betrachtet ausschließlich die eigenen Eigenschaften eines object. Wird nach einer Eigenschaft gefragt, die das object von seinem Prototyp erbt (oder nach einer Eigenschaft, die gar nicht existiert), gibt die Methode undefined zurück.


javascript— editable

Weitere Informationen darüber, wie objects Eigenschaften erben, finden Sie unter Prototypal Inheritance.

Data Descriptors vs. Accessor Descriptors

Bisher haben wir Data Descriptors beschrieben, die einen value zusammen mit dem writable-Flag speichern. JavaScript unterstützt außerdem Accessor Descriptors, die value/writable durch Getter- und Setter-Funktionen ersetzen:

  • get: Eine Funktion, die beim Lesen der Eigenschaft aufgerufen wird (ohne Argumente).
  • set: Eine Funktion, die beim Zuweisen eines Wertes zur Eigenschaft aufgerufen wird (erhält den neuen Wert).

Ein Descriptor ist entweder ein Data Descriptor oder ein Accessor Descriptor — niemals beides gleichzeitig. Die Kombination von value/writable mit get/set führt zu einem Fehler. Beide Typen teilen die Flags enumerable und configurable.

Accessor Properties werden verwendet, um einen Wert beim Lesen zu berechnen oder beim Schreiben zu validieren. Im folgenden Beispiel wird ein fullName-Accessor auf Basis zweier Data Properties bereitgestellt:


javascript— editable

Eine ausführlichere Behandlung der get/set-Syntax (einschließlich der Kurzschreibweise in object-Literalen) finden Sie unter Property Getters and Setters. Da Getter und Setter mit this gebunden an das object ausgeführt werden, ist es hilfreich, Object Methods and "this" zu verstehen.

Mehrere Eigenschaften gleichzeitig definieren und auslesen

Für die Arbeit mit mehreren Eigenschaften in einem Schritt stellt JavaScript die Gegenstücke der oben genannten Methoden bereit:

  • Object.defineProperties(obj, descriptors) definiert mehrere Eigenschaften aus einer Map von Descriptors.
  • Object.getOwnPropertyDescriptors(obj) gibt Descriptors für alle eigenen Eigenschaften (einschließlich nicht-aufzählbarer und Symbol-Schlüssel) als einzelnes object zurück.

Object.getOwnPropertyDescriptors ist besonders nützlich, um ein object mitsamt seinen Flags zu klonen — ein einfaches Spread oder Object.assign kopiert zwar die Werte, setzt jedoch alle Flags auf true zurück und überspringt Accessors.


javascript— editable

Property Flags manipulieren

Das Verstehen und Manipulieren von Property Flags ist entscheidend für eine effektive JavaScript-Entwicklung. Schauen wir uns an, wie man diese Flags steuert, um das Verhalten von Eigenschaften präzise anzupassen.

Eine Eigenschaft als nicht-schreibbar markieren

Das Verhindern von Änderungen an einer Eigenschaft stellt die Datenkonsistenz sicher. Dies erreicht man, indem das writable-Flag auf false gesetzt wird.


javascript— editable

Das Verhalten einer fehlgeschlagenen Zuweisung hängt davon ab, in welchem Modus der Code ausgeführt wird. Im Non-Strict-Modus schlägt das Schreiben in eine nicht-schreibbare Eigenschaft lautlos fehl: Die Zuweisung wird einfach ignoriert, es wird kein Fehler ausgelöst, und die Ausführung wird fortgesetzt — was Fehler verschleiern kann. Im Strict Mode ("use strict", und standardmäßig innerhalb von ES-Modulen und Klassen-Bodies) löst dieselbe Zuweisung einen TypeError aus. Diese Regel gilt für jede Operation, die ein Flag verletzt: Das Löschen einer nicht-konfigurierbaren Eigenschaft oder das Hinzufügen einer Eigenschaft zu einem nicht-erweiterbaren object schlägt im Non-Strict-Modus ebenfalls lautlos fehl und wirft im Strict Mode einen Fehler.


javascript— editable

Eine Eigenschaft vor der Aufzählung verbergen

Manchmal ist es notwendig, Eigenschaften vor Aufzählungsprozessen wie for...in-Schleifen zu verbergen. Dies erreicht man, indem das enumerable-Flag auf false gesetzt wird.


javascript— editable

Löschen und Ändern von Eigenschaften verhindern

Um sicherzustellen, dass eine Eigenschaft ein fester Bestandteil eines object bleibt, setzen Sie das configurable-Flag auf false.


javascript— editable

Eine Eigenschaft als nicht-konfigurierbar zu markieren ist eine unumkehrbare Operation — es gibt kein Flag, um sie wieder konfigurierbar zu machen, und man kann enumerable nicht mehr umschalten oder die Eigenschaft zwischen einem Data und einem Accessor Descriptor wechseln.

Es gibt jedoch zwei wichtige Ausnahmen, solange eine Eigenschaft nicht-konfigurierbar ist:

  • Das writable-Flag darf von true auf false geändert werden (aber nicht zurück von false auf true).
  • Wenn die Eigenschaft noch writable: true ist, kann ihr value geändert werden — entweder durch direkte Zuweisung oder über Object.defineProperty.

Mit anderen Worten: configurable: false sperrt die Form der Eigenschaft, nicht zwingend ihren Wert. Um den Wert einer Eigenschaft wirklich einzufrieren, setzen Sie sowohl configurable: false als auch writable: false.


javascript— editable

Übergeordnete APIs auf Basis dieser Flags

Flags müssen selten für jede Eigenschaft einzeln gesetzt werden. JavaScript bietet drei eingebaute Methoden, die diese Flags für ein gesamtes object umschalten:

  • Object.preventExtensions(obj) — verhindert, dass neue Eigenschaften hinzugefügt werden. Bestehende Eigenschaften können weiterhin geändert oder gelöscht werden.
  • Object.seal(obj) — verhindert das Hinzufügen und Löschen von Eigenschaften, indem jede bestehende Eigenschaft als configurable: false markiert wird. Werte können sich noch ändern.
  • Object.freeze(obj) — am restriktivsten: versiegelt das object und macht jede Eigenschaft writable: false, sodass nichts hinzugefügt, entfernt oder geändert werden kann.

Jede Methode hat eine entsprechende Prüffunktion: Object.isExtensible, Object.isSealed und Object.isFrozen. Beachten Sie, dass diese Methoden nur eine Ebene tief wirken — Object.freeze friert keine verschachtelten objects ein (es handelt sich um ein "flaches" Einfrieren).


javascript— editable

Fazit

Property Flags und Descriptors geben Ihnen präzise Kontrolle darüber, wie sich object-Eigenschaften verhalten:

  • Ein Data Descriptor kombiniert einen value mit writable; ein Accessor Descriptor verwendet stattdessen get/set-Funktionen. Beide teilen enumerable und configurable.
  • Flags werden mit Object.getOwnPropertyDescriptor (eine Eigenschaft) oder Object.getOwnPropertyDescriptors (alle eigenen Eigenschaften) gelesen; geschrieben werden sie mit Object.defineProperty oder Object.defineProperties. Geerbte und fehlende Eigenschaften geben undefined zurück.
  • configurable: false ist unumkehrbar und sperrt die Form der Eigenschaft — allerdings kann eine noch-writable Eigenschaft ihren Wert ändern und ihr writable-Flag auf false setzen.
  • Ein Verstoß gegen ein Flag schlägt im Non-Strict-Modus lautlos fehl, wirft jedoch im Strict Mode einen TypeError.
  • Greifen Sie auf Object.freeze, Object.seal und Object.preventExtensions zurück, wenn Sie ein gesamtes object statt einzelner Flags sperren möchten.

Nächste Schritte: Tauchen Sie ein in Property Getters and Setters für die Accessor-Syntax, Object Methods and "this" für das Verhalten von this darin, und Prototypal Inheritance, um zu sehen, wie die Eigenschaftssuche die Prototyp-Kette durchläuft.

Übungen

Übung
Was sind in JavaScript die Eigenschaften, die durch Property Descriptors definiert werden können?
Was sind in JavaScript die Eigenschaften, die durch Property Descriptors definiert werden können?
Was this page helpful?