Signatur
Beschreibung
Die statische Methode Object.freeze() friert ein Objekt ein. Das Einfrieren eines Objekts verhindert Erweiterungen und macht bestehende Eigenschaften nicht schreibbar und nicht konfigurierbar. Ein eingefrorenes Objekt kann nicht mehr verändert werden: Neue Eigenschaften können nicht hinzugefügt, bestehende Eigenschaften nicht entfernt werden, ihre Aufzählbarkeit, Konfigurierbarkeit, Schreibbarkeit oder ihr Wert können nicht geändert werden, und der Prototype des Objekts kann nicht neu zugewiesen werden. freeze() gibt dasselbe Objekt zurück, das übergeben wurde.
Das Einfrieren eines Objekts ist die höchste Integritätsstufe, die JavaScript bietet.
Das Einfrieren eines Objekts entspricht dem Verhindern von Erweiterungen und dem anschließenden Ändern aller vorhandenen Deskriptor-Attribute configurable auf false — und bei Dateneigenschaften zusätzlich writable auf false. Zu den Eigenschaften eines eingefrorenen Objekts kann nichts hinzugefügt oder daraus entfernt werden. Jeder derartige Versuch schlägt fehl, entweder still oder durch Werfen einer TypeError-Ausnahme (am häufigsten, aber nicht ausschließlich im strict mode).
Bei Dateneigenschaften eines eingefrorenen Objekts können deren Werte nicht geändert werden, da die Attribute writable und configurable auf false gesetzt sind. Zugriffseigenschaften (Getter und Setter) funktionieren gleich — der vom Getter zurückgegebene Eigenschaftswert kann sich weiterhin ändern, und der Setter kann weiterhin aufgerufen werden, ohne Fehler zu werfen, wenn die Eigenschaft gesetzt wird. Beachten Sie, dass Werte, die Objekte sind, weiterhin verändert werden können, es sei denn, sie sind ebenfalls eingefroren. Als Objekt kann auch ein Array eingefroren werden; danach können seine Elemente nicht verändert und keine Elemente hinzugefügt oder entfernt werden.
Private elements sind keine Eigenschaften und haben kein Konzept von Property Descriptors. Das Einfrieren eines Objekts mit private elements verhindert nicht, dass die Werte dieser private elements geändert werden. (Das Einfrieren von Objekten ist meist als Sicherheitsmaßnahme gegen externen Code gedacht, aber externer Code kann ohnehin nicht auf private elements zugreifen.) Private elements können weder hinzugefügt noch aus dem Objekt entfernt werden, unabhängig davon, ob das Objekt eingefroren ist oder nicht.
freeze() gibt dasselbe Objekt zurück, das an die Funktion übergeben wurde. Es erstellt keine eingefrorene Kopie.
Ein TypedArray oder ein DataView mit Elementen verursacht einen TypeError, da diese Ansichten über den Speicher sind und definitiv weitere mögliche Probleme verursachen würden.
Beachten Sie, dass die drei Standardeigenschaften (buf.byteLength, buf.byteOffset und buf.buffer) schreibgeschützt sind (ebenso wie die eines ArrayBuffer oder SharedArrayBuffer), sodass es keinen Grund gibt, diese Eigenschaften einzufrieren zu versuchen.
Im Gegensatz zu Object.seal() werden bestehende Eigenschaften in mit Object.freeze() eingefrorenen Objekten unveränderlich, und Dateneigenschaften können nicht neu zugewiesen werden.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $obj Pflicht | Object | — | Das einzufrierende Objekt. |
Rückgabewert
Beispiele
Objekte einfrieren
const obj = {
prop() {},
foo: "bar",
};
// Vor dem Einfrieren: neue Eigenschaften können hinzugefügt werden,
// und vorhandene Eigenschaften können geändert oder entfernt werden
obj.foo = "baz";
obj.lumpy = "woof";
delete obj.prop;
// Einfrieren.
const o = Object.freeze(obj);
// Der Rückgabewert ist genau dasselbe Objekt, das wir übergeben haben.
o === obj; // true
// Das Objekt ist nun eingefroren.
Object.isFrozen(obj); // === true
// Jetzt schlagen alle Änderungen fehl
obj.foo = "quux"; // tut still nichts
// fügt die Eigenschaft still nicht hinzu
obj.quaxxor = "the friendly duck";
// Im strict mode werfen solche Versuche TypeErrors
function fail() {
"use strict";
obj.foo = "sparky"; // wirft einen TypeError
delete obj.foo; // wirft einen TypeError
delete obj.quaxxor; // gibt true zurück, da das Attribut 'quaxxor' nie hinzugefügt wurde
obj.sparky = "arf"; // wirft einen TypeError
}
fail();
// Versuchte Änderungen über Object.defineProperty;
// beide Anweisungen unten werfen einen TypeError.
Object.defineProperty(obj, "ohai", { value: 17 });
Object.defineProperty(obj, "foo", { value: "eit" });
// Es ist auch unmöglich, den Prototype zu ändern
// beide Anweisungen unten werfen einen TypeError.
Object.setPrototypeOf(obj, { x: 20 });
obj.__proto__ = { x: 20 };
Arrays einfrieren
const a = [0];
Object.freeze(a); // Das Array kann jetzt nicht mehr verändert werden.
a[0] = 1; // schlägt still fehl
// Im strict mode wirft ein solcher Versuch einen TypeError
function fail() {
"use strict";
a[0] = 1;
}
fail();
// Versuch zu pushen
a.push(2); // wirft einen TypeError
Einfrieren ist flach
const obj1 = {
internal: {},
};
Object.freeze(obj1);
obj1.internal.a = "value";
obj1.internal.a; // 'value'
Deep Freezing
const employee = {
name: "Mayank",
designation: "Developer",
address: {
street: "Rohini",
city: "Delhi",
},
};
Object.freeze(employee);
employee.name = "Dummy"; // schlägt im non-strict mode still fehl
employee.address.city = "Noida"; // Attribute des Kindobjekts können verändert werden
console.log(employee.address.city); // "Noida"
deepFreeze-Implementierung
function deepFreeze(object) {
// Die auf dem Objekt definierten Eigenschaftsnamen abrufen
const propNames = Reflect.ownKeys(object);
// Eigenschaften einfrieren, bevor das Objekt selbst eingefroren wird
for (const name of propNames) {
const value = object[name];
if ((value && typeof value === "object") || typeof value === "function") {
deepFreeze(value);
}
}
return Object.freeze(object);
}
const obj2 = {
internal: {
a: null,
},
};
deepFreeze(obj2);
obj2.internal.a = "anotherValue"; // schlägt im non-strict mode still fehl
obj2.internal.a; // null
TypedArray und DataView einfrieren
Object.freeze(new Uint8Array(0)); // Keine Elemente
// Uint8Array []
Object.freeze(new Uint8Array(1)); // Hat Elemente
// TypeError: Cannot freeze array buffer views with elements
Object.freeze(new DataView(new ArrayBuffer(32))); // Keine Elemente
// DataView {}
Object.freeze(new Float64Array(new ArrayBuffer(64), 32, 0)); // Keine Elemente
// Float64Array []
Object.freeze(new Float64Array(new ArrayBuffer(64), 32, 2)); // Hat Elemente
// TypeError: Cannot freeze array buffer views with elements