Start · Sprachen · JavaScript · Referenz · Object.seal()

Object.seal()

Methode

Versiegelt ein Objekt: Es lassen sich keine Eigenschaften mehr hinzufügen oder löschen, vorhandene beschreibbare Werte bleiben aber änderbar.

seit JavaScript ES5 (ES2015: Nicht-Objekte werden ohne Fehler zurü Kategorie: method-property

Signatur

Object.seal(obj)

Beschreibung

Object.seal() versiegelt das übergebene Objekt direkt und gibt dasselbe Objekt zurück. Danach ist das Objekt nicht mehr erweiterbar (wie bei Object.preventExtensions()), und alle eigenen Eigenschaften werden auf configurable: false gesetzt. Man kann also keine Eigenschaften mehr hinzufügen oder löschen und die Attribute vorhandener Eigenschaften nicht umdefinieren. Außerdem lässt sich der Prototyp nicht mehr ändern.

Anders als bei Object.freeze() bleiben die Werte beschreibbarer Eigenschaften änderbar. Das passt gut, wenn die Form eines Objekts feststehen soll (z. B. ein Konfigurations- oder Zustandsobjekt mit festen Schlüsseln), die Inhalte sich aber ändern dürfen. So fallen Tippfehler bei Eigenschaftsnamen auf, statt dass still und leise neue Eigenschaften entstehen.

Wird versucht, ein versiegeltes Objekt zu erweitern oder Eigenschaften zu löschen, passiert im nicht-strikten Modus einfach nichts. Im Strict Mode (also auch in ES-Modulen und Klassen) wird ein TypeError geworfen. Ob ein Objekt versiegelt ist, prüft man mit Object.isSealed().

Parameter

Name Typ Default Beschreibung
$obj Pflicht any Das Objekt, das versiegelt werden soll. Primitive Werte werden seit ES2015 unverändert zurückgegeben.

Rückgabewert

Typ
any
Beschreibung
Dasselbe (jetzt versiegelte) Objekt, das übergeben wurde. Es wird keine Kopie erzeugt.

Beispiele

Grundverhalten: Werte ändern ja, Struktur ändern nein

const user = { name: 'Anna', role: 'admin' };
Object.seal(user);

user.name = 'Ben';      // erlaubt
user.email = 'b@x.de';  // wird ignoriert (nicht-strikter Modus)
delete user.role;       // wird ignoriert

console.log(user);
console.log(Object.isSealed(user));
{ name: 'Ben', role: 'admin' } true

Strict Mode: Tippfehler werden zu Fehlern

'use strict';

const state = Object.seal({ count: 0, loading: false });

try {
  state.cuont = 1; // Tippfehler im Namen
} catch (err) {
  console.log(err instanceof TypeError, err.message);
}

state.count += 1;
console.log(state.count);
true Cannot add property cuont, object is not extensible 1

Klasse mit fester Instanz-Struktur

class Point {
  constructor(x, y) {
    this.x = x;
    this.y = y;
    Object.seal(this); // nach dem Anlegen aller Felder versiegeln
  }
}

const p = new Point(1, 2);
p.x = 10;
console.log(p, Object.isExtensible(p));
console.log(Object.getOwnPropertyDescriptor(p, 'x'));
Point { x: 10, y: 2 } false { value: 10, writable: true, enumerable: true, configurable: false }

Versiegelung ist flach

const config = Object.seal({ db: { host: 'localhost' } });

config.db.port = 5432; // verschachteltes Objekt ist NICHT versiegelt
console.log(config.db);

// Tiefes Versiegeln rekursiv
const deepSeal = (obj) => {
  Object.values(obj).forEach((v) => {
    if (v && typeof v === 'object') deepSeal(v);
  });
  return Object.seal(obj);
};

const cfg = deepSeal({ db: { host: 'localhost' } });
console.log(Object.isSealed(cfg.db));
{ host: 'localhost', port: 5432 } true

// Wichtig · Fallstricke

  • Flach: Nur die eigenen Eigenschaften des Objekts werden versiegelt, verschachtelte Objekte und Arrays nicht. Für tiefes Versiegeln rekursiv vorgehen.
  • Kann nicht rückgängig gemacht werden: Ein versiegeltes Objekt lässt sich nicht wieder „entsiegeln“. Wer es erweitern muss, legt eine Kopie an (z. B. { ...obj }), denn die Kopie ist nicht versiegelt.
  • Stilles Scheitern: Außerhalb des Strict Mode werden verbotene Änderungen ohne Meldung ignoriert. Das kann Fehler verschleiern.
  • Beschreibbar bleibt beschreibbar: Eine Eigenschaft kann noch von writable: true auf false umgestellt werden, aber nicht zurück.
  • Arrays: Bei einem versiegelten Array schlagen push(), pop() und splice() fehl (TypeError), denn sie ändern die Länge. Vorhandene Elemente lassen sich aber per Index überschreiben.
  • Primitive Werte: In ES5 warf Object.seal(1) einen TypeError. Seit ES2015 wird der Wert einfach zurückgegeben.
  • Nicht anwendbar auf TypedArrays mit Elementen, dort wirft der Aufruf einen TypeError.
  • Wird von allen modernen Browsern und von Node.js unterstützt.