Object.freeze

Object.freeze() 静态方法可以使一个对象被冻结。冻结对象可以防止扩展,并使现有的属性不可写入和不可配置。被冻结的对象不能再被更改:不能添加新的属性,不能移除现有的属性,不能更改它们的可枚举性、可配置性、可写性或值,对象的原型也不能被重新指定。

冻结一个对象相当于阻止其扩展(Object.preventExtensions),然后将所有现有属性的描述符的 configurable 特性更改为 false——对于数据属性,将同时把 writable 特性更改为 false。

几个相关规则

  • 一旦将属性的 configurable 特性定义为 false,即不可配置的,该属性就不能再改回可配置的了。
  • writable 特性只能由 true 再次改为 false,而不能由 false 改为 true。

属性描述符的两类

对象中的属性可以分为两类:

  • 数据属性:value、writable、configurable、enumerable。
  • 访问器属性:get、set、enumerable、configurable。

示例

const obj = { name: 'Tom', age: 18 };
Object.freeze(obj);

obj.age = 20;            // 静默失败(非严格模式)
console.log(obj.age);    // 18

delete obj.name;         // 静默失败
console.log(obj);        // { name: 'Tom', age: 18 }

Object.isFrozen(obj);    // true

注意:Object.freeze 是浅冻结,对象属性如果是引用类型(对象/数组),内部仍可修改:

const data = Object.freeze({ list: [1, 2, 3] });
data.list.push(4);       // OK,浅冻结只冻结一层
console.log(data.list);  // [1, 2, 3, 4]

如果需要深冻结,需要递归遍历所有嵌套属性逐个 Object.freeze,或使用 structuredClone 等替代方案。

来源整理自:vue3js.cn 面试官系列