Object.freeze(), object.seal() та object.assign() у JavaScript
Статичні методи об'єкта
JavaScript надає кілька важливих статичних методів для Object, які контролюють змінність об'єктів і копіювання властивостей.
Object.freeze()
Зробіть об'єкт повністю незмінним — не можна додавати, видаляти або змінювати властивості:
const config = Object.freeze({
apiUrl: "https://api.example.com",
timeout: 5000
});
config.apiUrl = "changed"; // ❌ Мовчки не вдається (викидає помилку в строгому режимі)
config.newProp = "value"; // ❌ Мовчки не вдається
delete config.timeout; // ❌ Мовчки не вдається
console.log(config.apiUrl); // "https://api.example.com" (незмінено)Поверхневе замороження
Object.freeze() є поверхневим — вкладені об'єкти не заморожуються:
const user = Object.freeze({
name: "Alice",
address: { city: "Kyiv" } // Вкладений об'єкт НЕ заморожений
});
user.name = "Bob"; // ❌ Не вдається
user.address.city = "Lviv"; // ✅ Працює! (вкладений об'єкт змінний)Глибоке замороження
function deepFreeze(obj) {
Object.freeze(obj);
Object.values(obj).forEach(value => {
if (typeof value === "object" && value !== null) {
deepFreeze(value);
}
});
return obj;
}Object.seal()
Запобігає додаванню або видаленню властивостей, але дозволяє змінювати існуючі значення:
const user = Object.seal({
name: "Alice",
age: 25
});
user.name = "Bob"; // ✅ Можна змінювати існуючі властивості
user.email = "a@b.com"; // ❌ Не можна додавати нові властивості
delete user.age; // ❌ Не можна видаляти властивості
console.log(user); // { name: "Bob", age: 25 }Порівняння: freeze vs seal vs regular
| Операція | Звичайний об'єкт | Object.seal() | Object.freeze() |
|---|---|---|---|
| Читання властивостей | ✅ | ✅ | ✅ |
| Зміна значень | ✅ | ✅ | ❌ |
| Додавання властивостей | ✅ | ❌ | ❌ |
| Видалення властивостей | ✅ | ❌ | ❌ |
| Переналаштування дескрипторів | ✅ | ❌ | ❌ |
Перевірка стану об'єкта
Object.isFrozen(frozenObj); // true
Object.isSealed(sealedObj); // true
Object.isExtensible(regularObj); // true (можна додавати властивості)Object.assign()
Копіює перераховувані власні властивості з одного або кількох джерел до цільового об'єкта:
const target = { a: 1 };
const source1 = { b: 2 };
const source2 = { c: 3 };
const result = Object.assign(target, source1, source2);
console.log(result); // { a: 1, b: 2, c: 3 }
console.log(target); // { a: 1, b: 2, c: 3 } — цільовий об'єкт ЗМІНЮЄТЬСЯ!
console.log(result === target); // trueЗагальні шаблони
// Злиття без мутації (створити новий об'єкт)
const merged = Object.assign({}, defaults, userSettings);
// Те ж саме з оператором розподілу (бажано)
const merged = { ...defaults, ...userSettings };
// Клонування об'єкта (поверхневе)
const clone = Object.assign({}, original);
const clone = { ...original }; // Те ж самеПопередження про поверхневе копіювання
const original = {
name: "Alice",
address: { city: "Kyiv" }
};
const copy = Object.assign({}, original);
copy.address.city = "Lviv";
console.log(original.address.city); // "Lviv" — вкладений об'єкт спільний!Object.preventExtensions()
Запобігає додаванню нових властивостей, але дозволяє зміну та видалення:
const obj = Object.preventExtensions({ a: 1, b: 2 });
obj.a = 10; // ✅ Можна змінювати
delete obj.b; // ✅ Можна видаляти
obj.c = 3; // ❌ Не можна додаватиВажливо:
Використовуйте Object.freeze() для констант і об'єктів конфігурації. Використовуйте Object.seal(), коли хочете дозволити зміни, але запобігти структурним змінам. Віддавайте перевагу оператору розподілу ({ ...obj }) замість Object.assign() для створення копій. Пам'ятайте, що всі ці операції є поверхневими.
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.