1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
|
---
title: Object.freeze()
slug: Web/JavaScript/Reference/Global_Objects/Object/freeze
tags:
- ECMAScript5
- JavaScript
- Methode(2)
- Objekt
translation_of: Web/JavaScript/Reference/Global_Objects/Object/freeze
---
<div>{{JSRef}}</div>
<p>Die Methode <code><strong>Object.freeze()</strong></code> <strong>friert</strong> ein Objekt <strong>ein</strong>. Ein eingefrorenes Objekt kann nicht mehr geändert werden. Das Einfrieren eines Objekts verhindert, dass neue Eigenschaften hinzugefügt oder existierende entfernt und die Aufzählbarkeit, Konfigurierbarkeit oder Schreibbarkeit vorhandener Eigenschaften und deren Werte geändert werden können. Durch das Einfrieren eines Objekts wird außerdem verhindert, dass der Prototyp geändert wird. <code>freeze()</code> gibt das gleiche Objekt zurück, das übergeben wurde.</p>
<div>{{EmbedInteractiveExample("pages/js/object-freeze.html")}}</div>
<h2 id="Syntax">Syntax</h2>
<pre class="syntaxbox"><code>Object.freeze(<var>obj</var>)</code></pre>
<h3 id="Parameter">Parameter</h3>
<dl>
<dt><code>obj</code></dt>
<dd>Das einzufrierende Objekt.</dd>
</dl>
<h3 id="Rückgabewert">Rückgabewert</h3>
<p>Das Objekt, welches an die Funktion übergeben wurde.</p>
<h2 id="Beschreibung">Beschreibung</h2>
<p>Zum Eigenschaftssatz eines eingefrorenen Objekts kann nichts hinzugefügt oder daraus entfernt werden. Jeder Versuch, dies zu tun, schlägt fehl, entweder im Hintergrund oder durch Auslösen einer {{jsxref("TypeError")}} Exception (meistens, jedoch nicht ausschließlich, wenn im {{jsxref("Strict_mode", "strikten Modus", "", 1)}}).</p>
<p>Bei Dateneigenschaften eines eingefrorenen Objekts können Werte nicht geändert werden. Die Attribute für Beschreibbarkeit und Konfigurierbarkeit werden auf false gesetzt. Accessor-Eigenschaften (Getter und Setter) funktionieren gleich (und lassen einen nach wie vor in dem Glauben etwas zu ändern). Beachten Sie, dass Werte, die Objekte sind, immer noch geändert werden können, es sei denn, sie werden ebenfalls eingefroren. Da ein Array ein Objekt ist, kann es eingefroren werden. Danach können seine Elemente nicht mehr geändert und keine Elemente hinzugefügt oder entfernt werden.</p>
<p><code>freeze()</code> gibt das gleiche Objekt zurück, das an die Funktion übergeben wurde. Es wird <em>keine</em> eingefrorene Kopie erstellt.</p>
<h2 id="Beispiele">Beispiele</h2>
<h3 id="Objekte_einfrieren">Objekte einfrieren</h3>
<pre class="brush: js">var obj = {
prop: function() {},
foo: 'bar'
};
// Vor dem Einfrieren: neue Eigenschaften können hinzugefügt
// und vorhandene Eigenschaften geändert oder entfernt werden
obj.foo = 'baz';
obj.lumpy = 'woof';
delete obj.prop;
// Einfrieren
var o = Object.freeze(obj);
// Der Rückgabewert ist dasselbe Objekt, das übergeben wurde
o === obj; // true
// Das Objekt ist eingefroren
Object.isFrozen(obj); // === true
// Jetzt schlagen sämtliche Änderungen fehl
obj.foo = 'quux'; // nichts passiert, im Stillen
// fügt die Eigenschaft nicht hinzu, im Stillen
obj.quaxxor = 'the friendly duck';
// Im strikten Modus lösen solche Versuche TypeErrors aus
function fail(){
'use strict';
obj.foo = 'sparky'; // löst TypeError aus
delete obj.foo; // löst TypeError aus
delete obj.quaxxor; // gibt true zurück, da Attribut 'quaxxor' nie hinzugefügt wurde
obj.sparky = 'arf'; // löst TypeError aus
}
fail();
// Versuchte Änderungen über Object.defineProperty;
// beide Anweisungen lösen TypeError aus
Object.defineProperty(obj, 'ohai', { value: 17 });
Object.defineProperty(obj, 'foo', { value: 'eit' });
// Der prototype kann ebenfalls nicht geändert werden
// beide Anweisungen lösen TypeError aus
Object.setPrototypeOf(obj, { x: 20 })
obj.__proto__ = { x: 20 }
</pre>
<h3 id="Arrays_einfrieren">Arrays einfrieren</h3>
<pre class="brush: js">let a = [0];
Object.freeze(a); // Das Array kann nicht mehr geändert werden
a[0]=1; // schlägt still fehl
a.push(2); // schlägt still fehl
// Im strikten Modus lösen solche Versuche TypeErrors aus
function fail() {
"use strict"
a[0] = 1;
a.push(2);
}
fail();</pre>
<p>Das eingefrorene Objekt ist <em>unveränderlich</em> (engl. <em>immutable</em>). Es ist jedoch nicht notwendigerweise <em>konstant</em>. Das folgende Beispiel zeigt, dass ein eingefrorenes Objekt nicht konstant ist (Einfrieren ist flach).</p>
<pre class="brush: js">obj1 = {
internal: {}
};
Object.freeze(obj1);
obj1.internal.a = 'aValue';
obj1.internal.a // 'aValue'</pre>
<p>Um ein konstantes Objekt zu sein, muss der gesamte Referenzgraph (direkte und indirekte Verweise auf andere Objekte) nur unveränderliche eingefrorene Objekte referenzieren. Das eingefrorene Objekt wird als unveränderlich (immutable) bezeichnet, da der gesamte <em>Objektzustand</em> (Werte und Verweise auf andere Objekte) innerhalb des gesamten Objekts fix ist. Beachten Sie, dass Strings, Zahlen und Booleans immer unveränderlich (immutable) und Funktionen und Arrays Objekte sind.</p>
<h4 id="Was_ist_flaches_Einfrieren">Was ist "flaches Einfrieren"?</h4>
<p>Das Ergebnis des Aufrufs von <code>Object.freeze(<var>object</var>)</code> gilt nur für die unmittelbaren Eigenschaften von <code>object</code> selbst und verhindert, dass zukünftige Eigenschaften hinzugefügt, entfernt oder Werte auf <em>diesem</em> <code>object</code> neu zugewiesen werden. Wenn der Wert dieser Eigenschaften selbst Objekte sind, werden diese Objekte nicht eingefroren und können das Ziel von Eigenschaftszusatz-, Entfernungs- oder Wertzuordnungsvorgängen sein.</p>
<pre class="brush: js">var employee = {
name: "Mayank",
designation: "Developer",
address: {
street: "Rohini",
city: "Delhi"
}
};
Object.freeze(employee);
employee.name = "Dummy"; // schlägt im nicht-strikten Modus still fehl
employee.address.city = "Noida"; // Attribute von Kind-Objekt können geändert werden
console.log(employee.address.city) // Ausgabe: "Noida"
</pre>
<p>Um ein Objekt unveränderlich zu machen, frieren Sie rekursiv jede Eigenschaft vom Typ <code>object</code> ein (deep freeze). Verwenden Sie das Muster im Einzelfall basierend auf Ihrem Entwurf, wenn Sie wissen, dass das Objekt keine {{interwiki("wikipedia", "Zyklus_(Graphentheorie)", "Zyklen")}} im Referenzgraph enthält, andernfalls kommt es zu einer Endlosschleife. Eine Verbesserung von <code>deepFreeze()</code> wäre eine interne Funktion, die ein Argument für einen Pfad (z. B. ein Array) empfängt, sodass Sie den Aufruf von <code>deepFreeze()</code> rekursiv unterdrücken können, wenn ein Objekt gerade unveränderlich gemacht wird. Es besteht weiterhin die Gefahr, dass ein Objekt eingefroren wird, das nicht eingefroren werden sollte, wie z. B. [window].</p>
<pre class="brush: js">function deepFreeze(object) {
// Abrufen der definierten Eigenschaftsnamen des Objekts
var propNames = Object.getOwnPropertyNames(object);
// Eigenschaften vor dem eigenen Einfrieren einfrieren
for (let name of propNames) {
let value = object[name];
object[name] = value && typeof value === "object" ?
deepFreeze(value) : value;
}
return Object.freeze(object);
}
var obj2 = {
internal: {
a: null
}
};
deepFreeze(obj2);
obj2.internal.a = 'anotherValue'; // schlägt im nicht-strikten Modus still fehl
obj2.internal.a; // null
</pre>
<h2 id="Nutzungshinweise">Nutzungshinweise</h2>
<p>Wenn das Argument für diese Methode kein Objekt (ein Primitiv) ist, führt dies in ES5 zu einem {{jsxref("TypeError")}}. In ES2015 wird ein Nicht-Objekt-Argument wie ein eingefrorenes gewöhnliches Objekt behandelt und einfach zurückgegeben.</p>
<pre class="brush: js">> Object.freeze(1)
TypeError: 1 is not an object // ES5 Code
> Object.freeze(1)
1 // ES2015 Code
</pre>
<p>Ein {{domxref("ArrayBufferView")}} mit Elementen verursacht einen {{jsxref("TypeError")}}, da diese Ansichten über den Arbeitsspeicher sind und auf jeden Fall andere mögliche Probleme verursachen können:</p>
<pre class="brush: js">> 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), 63, 0)) // Keine Elemente
Float64Array []
> Object.freeze(new Float64Array(new ArrayBuffer(64), 32, 2)) // Hat Elemente
TypeError: Cannot freeze array buffer views with elements
</pre>
<p>Beachten Sie, da die drei Standard-Eigenschaften (<code>buf.byteLength</code>, <code>buf.byteOffset</code> und <code>buf.buffer</code>) schreibgeschützt sind (wie die Eigenschaften eines {{jsxref("ArrayBuffer")}} oder {{jsxref("SharedArrayBuffer")}}) gibt es keinen Grund, diese einzufrieren.</p>
<h3 id="Vergleich_zu_Object.seal()">Vergleich zu <code>Object.seal()</code></h3>
<p>Vorhandene Eigenschaften in Objekten, die mit {{jsxref("Object.seal()")}} versiegelt wurden, können geändert werden. Vorhandene Eigenschaften in Objekten, die mit <code>Object.freeze()</code> eingefroren wurden, werden unveränderlich gemacht.</p>
<h2 id="Spezifikationen">Spezifikationen</h2>
<table class="standard-table">
<thead>
<tr>
<th scope="col">Specification</th>
<th scope="col">Status</th>
<th scope="col">Comment</th>
</tr>
</thead>
<tbody>
<tr>
<td>{{SpecName('ES5.1', '#sec-15.2.3.9', 'Object.freeze')}}</td>
<td>{{Spec2('ES5.1')}}</td>
<td>Initiale Definition. Implementiert in JavaScript 1.8.5.</td>
</tr>
<tr>
<td>{{SpecName('ES6', '#sec-object.freeze', 'Object.freeze')}}</td>
<td>{{Spec2('ES6')}}</td>
<td> </td>
</tr>
<tr>
<td>{{SpecName('ESDraft', '#sec-object.freeze', 'Object.freeze')}}</td>
<td>{{Spec2('ESDraft')}}</td>
<td> </td>
</tr>
</tbody>
</table>
<h2 id="Browserkompatibilität">Browserkompatibilität</h2>
<p>{{Compat("javascript.builtins.Object.freeze")}}</p>
<h2 id="Siehe_auch">Siehe auch</h2>
<ul>
<li>{{jsxref("Object.isFrozen()")}}</li>
<li>{{jsxref("Object.preventExtensions()")}}</li>
<li>{{jsxref("Object.isExtensible()")}}</li>
<li>{{jsxref("Object.seal()")}}</li>
<li>{{jsxref("Object.isSealed()")}}</li>
</ul>
|