According to the Object.freeze
documentation , no there is a ready method for this, it is necessary to create a special function to iterate over the object's fields and apply freeze
to each of them:
function deepFreeze (o) {
var prop, propKey;
Object.freeze(o); // Primeiro congela o objeto.
for (propKey in o) {
prop = o[propKey];
if (!o.hasOwnProperty(propKey) || !(typeof prop === "object") || Object.isFrozen(prop)) {
// Se o objeto está no prototype, não é um objeto, ou já está congelado, pule.
// Note que isso pode deixar uma referência não congelada em algum lugar no objeto
// se já existe um objeto congelado contendo outro objeto não congelado.
continue;
}
deepFreeze(prop); // Chama deepFreeze recursivamente.
}
}
Example of the special case mentioned in the code (to avoid it, comment on the part where it checks if the object is already frozen so as not to freeze it again):
var raso = { foo:{ bar:"baz" } };
Object.freeze(raso); // { bar:"baz" } continua não congelado
var fundo = { raso:raso }
deepFreeze(fundo); // raso não é afetado, pois já estava congelado
fundo.raso.foo.bar = 42; // Atribui corretamente
However, special care must be taken in cases where the object has circular references. This is not a problem in the above code as it stands (since "frozen" checking prevents the same object from being visited twice - thus avoiding an infinite loop), but becomes a problem if that test is removed .
Finally, it is good to mention that depending on the implementation freezing an object can negatively impact the performance (as cited #) - contrary to what would normally be expected, that such immutability would bring the possibility of optimizations that a mutable object does not allow.