Sobes.tech
Middle

Como pode impedir a alteração de um objeto em JavaScript?

sobes.tech IA

Resposta da IA

Pode usar os métodos incorporados de Object:

  1. Object.preventExtensions(obj): Proíbe a adição de novas propriedades ao objeto, mas permite modificar e eliminar as existentes.
  2. Object.seal(obj): Proíbe a adição e eliminação de propriedades, mas permite modificar as existentes. Na prática, isto é preventExtensions + proibição de eliminação.
  3. Object.freeze(obj): Proíbe adicionar, eliminar e modificar propriedades. Torna o objeto imutável em profundidade. Isto é seal + proibição de modificar as propriedades existentes.

Exemplo de uso:

// Objeto inicial
let myObject = { name: 'Alice', age: 30 };

// preventExtensions
Object.preventExtensions(myObject);
myObject.city = 'London'; // Não terá efeito em modo estrito, será ignorado em modo não estrito.

// seal
let mySealedObject = { name: 'Bob', age: 25 };
Object.seal(mySealedObject);
mySealedObject.age = 26; // Vai funcionar
delete mySealedObject.name; // Não vai funcionar em modo estrito.
mySealedObject.city = 'Paris'; // Não vai funcionar em modo estrito.

// freeze
let myFrozenObject = { name: 'Charlie', age: 35 };
Object.freeze(myFrozenObject);
myFrozenObject.age = 36; // Não vai funcionar em modo estrito.
delete myFrozenObject.name; // Não vai funcionar em modo estrito.
myFrozenObject.city = 'New York'; // Não vai funcionar em modo estrito.

É importante lembrar que Object.freeze é superficial. Se o objeto contém referências a outros objetos, esses objetos internos podem ser modificados se não estiverem congelados. Para congelar profundamente, é necessária uma função recursiva.

// Exemplo de congelamento profundo
function deepFreeze(obj) {
  Object.freeze(obj); // Congela o objeto atual

  for (const key in obj) {
    if (Object.prototype.hasOwnProperty.call(obj, key)) {
      const prop = obj[key];

      // Se a propriedade for um objeto (e não null), congela recursivamente
      if (typeof prop === 'object' && prop !== null && !Object.isFrozen(prop)) {
        deepFreeze(prop);
      }
    }
  }
}

let nestedObject = {
  name: 'Deep',
  details: {
    level: 1
  }
};

deepFreeze(nestedObject);
nestedObject.details.level = 2; // Não vai funcionar em modo estrito.

Tabela comparativa:

Método Adicionar propriedades Eliminar propriedades Modificar propriedades
Object.preventExtensions() Não Sim Sim
Object.seal() Não Não Sim
Object.freeze() Não Não Não