Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> JavaScript

Object.freeze() có làm bất biến nested object không?

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.