Cả hai đều làm object non-extensible (không thêm property mới) và non-configurable (không xóa/đổi descriptor property). Khác biệt: freeze còn làm writable: false.
Object.seal()
- Không thêm property mới.
- Không xóa property hiện có.
- Vẫn cho phép sửa value của property.
Ví dụ
<script>
const obj = { prop1: 1 };
Object.seal(obj);
obj.prop1 = 2; // OK — thay đổi value
delete obj.prop1; // Thất bại (strict: TypeError)
obj.newProp = 3; // Thất bại
document.write(obj.prop1); // 2
</script>
Object.freeze()
- Tất cả tính năng của
seal(). - Không cho sửa value property (writable: false).
- Object trở thành bất biến hoàn toàn (shallow immutable).
Ví dụ
<script>
const obj = { prop1: 1 };
Object.freeze(obj);
obj.prop1 = 2; // Thất bại (strict: TypeError)
delete obj.prop1; // Thất bại
obj.newProp = 3; // Thất bại
document.write(obj.prop1); // 1 — không đổi
</script>
Bảng so sánh
| Hành động | Normal | seal() | freeze() |
|---|---|---|---|
| Thêm property | ✓ | ✗ | ✗ |
| Xóa property | ✓ | ✗ | ✗ |
| Sửa value | ✓ | ✓ | ✗ |
| Sửa descriptor (defineProperty) | ✓ | ✗ | ✗ |
| Object.isSealed() | false | true | true |
| Object.isFrozen() | false | false | true |
Lưu ý quan trọng: Shallow only
Cả seal và freeze chỉ áp dụng mức 1 (shallow). Nested object vẫn có thể thay đổi.
const obj = { nested: { a: 1 } };
Object.freeze(obj);
obj.nested.a = 2; // THÀNH CÔNG! — nested không bị freeze
console.log(obj.nested.a); // 2
Deep Freeze (Đệ quy)
function deepFreeze(obj) {
Object.freeze(obj);
Object.keys(obj).forEach(key => {
if (typeof obj[key] === 'object' && obj[key] !== null) {
deepFreeze(obj[key]);
}
});
return obj;
}