前端知库

属性描述符、Object.freeze 和只读有什么区别?

参考答案

对象的属性可以是数据属性,也可以是访问器属性。数据属性包含 value、writable;访问器属性包含 get、set;两类都可具有 enumerable 和 configurable。Object.defineProperty 未显式指定的布尔特性默认是 false。

Object.preventExtensions 阻止新增属性;seal 还使已有属性不可配置;freeze 进一步使数据属性不可写。冻结是浅层的,嵌套对象仍可能变化;访问器属性的 getter 返回值也可能变化,setter 仍可被调用,Map 等内置集合的内部状态也不能仅靠 freeze 固定。

TypeScript 的 readonly 是编译时约束,不能替代运行时冻结。需要不可变数据时,应明确采用结构共享、受控更新或冻结策略,并评估深冻结在循环引用和性能上的代价。

可运行示例

JavaScript
const item = Object.freeze({ nested: { count: 0 } });
item.nested.count += 1;
console.log(item.nested.count);

输出依次为:1,说明冻结不会自动递归到嵌套对象。