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
|
---
title: Object.freeze()
slug: Web/JavaScript/Referencje/Obiekty/Object/freeze
translation_of: Web/JavaScript/Reference/Global_Objects/Object/freeze
---
<div>{{JSRef}}</div>
<div>Metoda <code><strong>Object.freeze()</strong> </code>"zamraża" obiekt, tzn. uniemożliwia dodawania nowych właściwości do obiektu; uniemożliwia usuwanie istniejących właściwości; uniemożliwia zmianę istniejących właściwości; oraz uniemożliwia zmianę prototypu obiektu. W efekcie obiekt jest naprawdę stały. Metoda zwraca obiekt w stanie "zamrożonym".</div>
<div> </div>
<h2 id="Składnia">Składnia</h2>
<pre class="syntaxbox"><code>Object.freeze(<var>obj</var>)</code></pre>
<h3 id="Argumenty">Argumenty</h3>
<dl>
<dt><code>obj</code></dt>
<dd>Obiekt który ma zostać "zamrożony".</dd>
</dl>
<h3 id="Zwracana_wartość">Zwracana wartość</h3>
<p>"Zamrożony" obiekt.</p>
<h2 id="Opis">Opis</h2>
<p>Nic nie może zostać dodane ani usunięte z "zamrożonego" obiektu. Każda próba tego wywoła błąd, albo po cichu, albo rzucając wyjątek {{jsxref("TypeError")}}(zawzwyczaj, choć nie zawsze, w przypadku używania {{jsxref("Strict_mode", "strict mode", "", 1)}}).</p>
<p>Nie ma możliwości zmiany wartości właściwości obiektu. Metody dostępu (gettery i settery) działają bez zmian (sprawiają wrażenie skutecznej zmiany właściwości obiektu). Zwróć uwagę na to, że wartości, które są obiektami w dalszym ciągu mogą być modyfikowane, chyba że również są "zamrożone". Z uwagi na to, że Tablica (Array) jest obiektem, również może zostać zamrożona co uniemożliwi zmianę jej elementów, ich usuwanie oraz dodawanie nowych. </p>
<h2 id="Przykłady">Przykłady</h2>
<p> </p>
<h3 id="Zamrażanie_Obiektów">Zamrażanie Obiektów</h3>
<p> </p>
<pre class="brush: js">var obj = {
prop: function() {},
foo: 'bar'
};
// Nowe właściwości mogą być dodawane, istniejące mogą być zmieniane oraz usuwane
obj.foo = 'baz';
obj.lumpy = 'woof';
delete obj.prop;
// Zarówno obiekt przekazywany w funkcji freeze() jak i obiekt zwracany bedą "zamrożone"
// Nie ma potrzeby przypisywania zwracanego obiektu do zmiennej jeśli chcemy tylko "zamrozić" obiekt przekazywany w funkcji
var o = Object.freeze(obj);
o === obj; // true
Object.isFrozen(obj); // === true
// Teraz wszelkie zmiany są niemożliwe
obj.foo = 'quux'; // brak rezultatu nieskutkujący wyświetleniem błędu
obj.quaxxor = 'the friendly duck'; // brak rezultatu nieskutkujący wyświetleniem błędu
// przy strict mode tego typu próby spowodują wyświetlenie komunikatu o błędzie
function fail(){
'use strict';
obj.foo = 'sparky'; // TypeError
delete obj.quaxxor; // TypeError
obj.sparky = 'arf'; // TypeError
}
fail();
// Próby zmian poprzez Object.defineProperty spowodują wyświetlenie komunikatu o błędzie
Object.defineProperty(obj, 'ohai', { value: 17 }); // TypeError
Object.defineProperty(obj, 'foo', { value: 'eit' }); // TypeError
// Niemożliwa jest również zmiana prototypu obiektu. Obie instrukcje poniżej wygenerują błąd
Object.setPrototypeOf(obj, { x: 20})
obj.__proto__ = { x: 20}
</pre>
<h3 id="Zamrażanie_Tablic_(Array)">Zamrażanie Tablic (Array)</h3>
<p> </p>
<pre class="brush: js"><code>let a = [0];
Object.freeze(a); // Tablica nie może być teraz modyfikowana
a[0]=1; // brak rezultatu nieskutkujący wyświetleniem błędu
a.push(2); // brak rezultatu nieskutkujący wyświetleniem błędu
// </code>przy strict mode tego typu próby spowodują wyświetlenie komunikatu o błędzie<code> TypeErrors
function fail() {
"use strict"
a[0] = 1;
a.push(2);
}
fail();</code></pre>
<p>"Zamrożony" obiekt jest <em>niemutowalny</em>. Nie jest on jednak <em>stałą</em>. Obrazuje to poniższy przykład.</p>
<pre class="brush: js"><code>obj1 = {
internal: {}
};
Object.freeze(obj1);
obj1.internal.a = 'aValue';
obj1.internal.a // 'aValue'</code>
</pre>
<p> </p>
<p>To be a constant object, the entire reference graph (direct and indirect references to other objects) must reference only immutable frozen objects. The object being frozen is said to be immutable because the entire object <em>state </em>(values and references to other objects) within the whole object is fixed. Note that strings, numbers, and booleans are always immutable and that Functions and Arrays are objects. </p>
<p>To make an object constant, recursively freeze each property which is of type object (deep freeze). Use the pattern on a case-by-case basis based on your design when you know the object contains no <em><a href="https://en.wikipedia.org/wiki/Cycle_(graph_theory)">cycles</a> </em>in the reference graph, otherwise an endless loop will be triggered. An enhancement to deepFreeze() would be to have an internal function that receives a path (e.g. an Array) argument so you can supress calling deepFreeze() recursively when an object is in the process of being made constant. You still run a risk of freezing an object that shouldn't be frozen, such as [window].</p>
<pre class="brush: js"><code>// To do so, we use this function.
function deepFreeze(obj) {
// Retrieve the property names defined on obj
var propNames = Object.getOwnPropertyNames(obj);
// Freeze properties before freezing self
propNames.forEach(function(name) {
var prop = obj[name];
// Freeze prop if it is an object
if (typeof prop == 'object' && prop !== null)
deepFreeze(prop);
});
// Freeze self (no-op if already frozen)
return Object.freeze(obj);
}
obj2 = {
internal: {}
};
deepFreeze(obj2);
obj2.internal.a = 'anotherValue';
obj2.internal.a; // unde</code></pre>
<p> </p>
<p> </p>
<h2 id="Notes">Notes</h2>
<p>In ES5, if the argument to this method is not an object (a primitive), then it will cause a {{jsxref("TypeError")}}. In ES2015, a non-object argument will be treated as if it were a frozen ordinary object, and be simply returned.</p>
<pre class="brush: js">> Object.freeze(1)
TypeError: 1 is not an object // ES5 code
> Object.freeze(1)
1 // ES2015 code
</pre>
<h2 id="Specifications">Specifications</h2>
<table class="standard-table">
<tbody>
<tr>
<th scope="col">Specification</th>
<th scope="col">Status</th>
<th scope="col">Comment</th>
</tr>
<tr>
<td>{{SpecName('ES5.1', '#sec-15.2.3.9', 'Object.freeze')}}</td>
<td>{{Spec2('ES5.1')}}</td>
<td>Initial definition. Implemented in JavaScript 1.8.5.</td>
</tr>
<tr>
<td>{{SpecName('ES2015', '#sec-object.freeze', 'Object.freeze')}}</td>
<td>{{Spec2('ES2015')}}</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="Browser_compatibility">Browser compatibility</h2>
<div>
<p>{{Compat("javascript.builtins.Object.freeze")}}</p>
</div>
<h2 id="See_also">See also</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>
|