Không. Object.freeze() là shallow freeze — chỉ đóng băng level 1 (property trực tiếp). Nested object bên trong vẫn có thể mutate.
Ví dụ: Object phẳng (không nested) — Freeze hoạt động
<script>
const person = { name: 'Suresh', country: 'India', designation: 'Mayor' };
document.write('Trước freeze: ' + person.name + '<br>'); // Suresh
Object.freeze(person);
person.name = 'John'; // Thất bại (strict: TypeError)
document.write('Sau freeze: ' + person.name); // Suresh — không đổi
</script>
Ví dụ: Nested object — Freeze KHÔNG bảo vệ
<script>
const person = {
name: 'Suresh',
companiesOwned: {
company1: 'Tesla',
company2: 'SolarCity',
company3: 'SpaceX'
}
};
document.write('Trước freeze: ' + person.companiesOwned.company2 + '<br>'); // SolarCity
Object.freeze(person);
person.companiesOwned.company2 = 'Neuralink'; // THÀNH CÔNG! — nested không bị freeze
document.write('Sau freeze: ' + person.companiesOwned.company2); // Neuralink
</script>
Kết quả
Trước freeze: SolarCity Sau freeze: Neuralink
Giải pháp: Deep Freeze (Đệ quy)
function deepFreeze(obj) {
// Freeze level 1
Object.freeze(obj);
// Đệ quy freeze các nested object
Object.keys(obj).forEach(key => {
const value = obj[key];
if (value && typeof value === 'object' && !Object.isFrozen(value)) {
deepFreeze(value);
}
});
return obj;
}
// Sử dụng
const person = {
name: 'Suresh',
companiesOwned: { company1: 'Tesla', company2: 'SolarCity' }
};
deepFreeze(person);
person.companiesOwned.company2 = 'Neuralink'; // Thất bại (strict mode)
console.log(person.companiesOwned.company2); // SolarCity — an toàn
Lưu ý Deep Freeze
- Cần kiểm tra
Object.isFrozen()để tránh freeze lặp vô tận (circular reference). - Không freeze được: function, Date, RegExp, DOM element, WeakMap/Set — bỏ qua hoặc throw.
- Performance: Deep freeze object lớn tốn tài nguyên — cân nhắc.
Thư viện hỗ trợ
Immer— Immutable state management (produce pattern).Immutable.js— Persistent data structures.deep-freeze(npm package) — Utility nhỏ gọn.