El mètode Object.freeze()
congela un objecte: és a dir, evita que se li puguin afegir noves propietats, eliminar propietats ja existents així com modificar els paràmetres d'enumerabilitat, configurabilitat i possibilitat d'escriptura de les propietats existents. Això, en essència fa que l'objecte esdevingui immutable a efectes pràctics. El mètode retorna l'objecte que s'ha congelat.
Sintaxi
Object.freeze(obj)
Paràmetres
obj
- L'objecte a congelar.
Descripció
Res pot ser afegit o eliminat del conjunt de propietats d'un objecte congelat. Qualsevol intent fallarà o bé sense reportar cap error o bé llençant una excepció TypeError
(és l'excepció més freqüent que serà llençada però en pot llençat altres tipus; a l'utilitzar el mode estricte).
Congelar un objecte també evita que es puguin modificar els valors de les seves propietats. Les propietats d'accés (getters i setters) segueixen funcionan (donant la il·lusió que s'ha canviat el valor). Cal advertir, però, que els valors que siguin objectes sí que es poden modificar, a no ser que aquests objectes també estiguin congelats.
Exemples
var obj = { prop: function() {}, foo: 'bar' }; // Es poden afegir noves propietats, així com canviar o eliminar les propietats ja existents obj.foo = 'baz'; obj.lumpy = 'woof'; delete obj.prop; var o = Object.freeze(obj); assert(Object.isFrozen(obj) === true); // A partir d'ara qualsevol canvi fallarà obj.foo = 'quux'; // falla silenciosament obj.quaxxor = 'the friendly duck'; // romàn en silenci i no afegeix la propietat // ...i en mode estricte qualsevol intent llençarà una excepció TypeError function fail(){ 'use strict'; obj.foo = 'sparky'; // llença TypeError delete obj.quaxxor; // llença TypeError obj.sparky = 'arf'; // llença TypeError } fail(); // Intentar realitzar canvis a través de Object.defineProperty també resultaran en excepcions Object.defineProperty(obj, 'ohai', { value: 17 }); // llença TypeError Object.defineProperty(obj, 'foo', { value: 'eit' }); // llença TypeError
L'exemple següent demostra que valors de tipus objecte pertanyents a propietats d'un objecte congelat sí que es poden modificar.(freeze
no s'aplica de manera recursiva).
obj1 = { internal: {} }; Object.freeze(obj1); obj1.internal.a = 'aValue'; obj1.internal.a // 'aValue' // Per a fer que obj sigui totalment immutable cal congelar tots els objectes referenciats per aquest. // Per a aconseguir això utilitzem la funció següent function deepFreeze(obj) { // Obté els nomes de les propietats definides a l'objecte obj var propNames = Object.getOwnPropertyNames(obj); // Congela les propietats abans de congelar l'objecte en si propNames.forEach(function(name) { var prop = obj[name]; // Congela prop si aquest és un objecte if (typeof prop == 'object' && !Object.isFrozen(prop)) deepFreeze(prop); }); // Congela l'objecte pare return Object.freeze(obj); } obj2 = { internal: {} }; deepFreeze(obj2); obj2.internal.a = 'anotherValue'; obj2.internal.a; // undefined
Notes
A l'EcmaScript 5, si l'argument passat a aquest mètode no és un objecte (un valor primitiu), llençarà un TypeError
. A l'EcmaScript 6, un argument que no sigui un objecte serà tractat com si fós un objecte congelat ordinari, i simplement el retornarà.
> Object.freeze(1) TypeError: 1 no és un objecte // Codi EcmaScript 5 > Object.freeze(1) 1 // Codi EcmaScript 6
Especificacions
Especificacions | Estat | Comentaris |
---|---|---|
ECMAScript 5.1 (ECMA-262) The definition of 'Object.freeze' in that specification. |
Standard | Definició inicial. Implementat a JavaScript 1.8.5. |
ECMAScript 2015 (6th Edition, ECMA-262) The definition of 'Object.freeze' in that specification. |
Standard |
Compatibilitat amb navegadors
Característica | Firefox (Gecko) | Chrome | Internet Explorer | Opera | Safari |
---|---|---|---|---|---|
Suport bàsic | 4.0 (2) | 6 | 9 | 12 | 5.1 |
Característica | Firefox Mobile (Gecko) | Android | IE Mobile | Opera Mobile | Safari Mobile |
---|---|---|---|---|---|
Suport bàsic | ? | ? | ? | ? | ? |