Sobes.tech
Middle

Jak można zabronić modyfikacji obiektu w JavaScript?

sobes.tech AI

Odpowiedź od AI

Możesz używać wbudowanych metod Object:

  1. Object.preventExtensions(obj): Zabrania dodawania nowych właściwości do obiektu, ale pozwala na modyfikację i usuwanie istniejących.
  2. Object.seal(obj): Zabrania dodawania i usuwania właściwości, ale pozwala na modyfikację istniejących. W praktyce jest to preventExtensions + zakaz usuwania.
  3. Object.freeze(obj): Zabrania dodawania, usuwania i modyfikacji właściwości. Czyni obiekt niezmiennym głęboko. To jest seal + zakaz modyfikacji istniejących właściwości.

Przykład użycia:

// Obiekt początkowy
let myObject = { name: 'Alice', age: 30 };

// preventExtensions
Object.preventExtensions(myObject);
myObject.city = 'London'; // Nie zadziała w trybie ścisłym, w trybie nieścisłym zostanie zignorowane.

// seal
let mySealedObject = { name: 'Bob', age: 25 };
Object.seal(mySealedObject);
mySealedObject.age = 26; // Zadziała
delete mySealedObject.name; // Nie zadziała w trybie ścisłym.
mySealedObject.city = 'Paris'; // Nie zadziała w trybie ścisłym.

// freeze
let myFrozenObject = { name: 'Charlie', age: 35 };
Object.freeze(myFrozenObject);
myFrozenObject.age = 36; // Nie zadziała w trybie ścisłym.
delete myFrozenObject.name; // Nie zadziała w trybie ścisłym.
myFrozenObject.city = 'New York'; // Nie zadziała w trybie ścisłym.

Ważne jest, aby pamiętać, że Object.freeze jest powierzchniowe. Jeśli obiekt zawiera odwołania do innych obiektów, te zagnieżdżone obiekty można modyfikować, jeśli same nie są zamrożone. Do głębokiego zamrażania potrzebna jest funkcja rekurencyjna.

// Przykład głębokiego zamrażania
function deepFreeze(obj) {
  Object.freeze(obj); // Zamraża bieżący obiekt

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

      // Jeśli właściwość jest obiektem (i nie jest null), zamrażamy ją rekurencyjnie
      if (typeof prop === 'object' && prop !== null && !Object.isFrozen(prop)) {
        deepFreeze(prop);
      }
    }
  }
}

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

deepFreeze(nestedObject);
nestedObject.details.level = 2; // Nie zadziała w trybie ścisłym.

Tabela porównawcza:

Metoda Dodawanie właściwości Usuwanie właściwości Modyfikacja właściwości
Object.preventExtensions() Nie Tak Tak
Object.seal() Nie Nie Tak
Object.freeze() Nie Nie Nie