writable 是属性级可写标志,frozen 是对象级不可变状态;Object.freeze() 会强制将所有自有数据属性的 writable 设为 false,但不影响访问器属性、嵌套对象及原型链属性。

writable 是属性描述符中的一个布尔特性,控制该属性的值能否被重新赋值;而 frozen 是对象整体的一种不可变状态,由 Object.freeze() 设置。二者不是等价关系,但存在明确的因果约束:当对象被冻结后,其所有**现有数据属性**的 writable 会被强制设为 false。
冻结会强制关闭 writable
调用 Object.freeze(obj) 后,对象中所有自有数据属性(即不含 getter/setter 的普通属性)的 writable 描述符都会变为 false。这意味着:
- 对这些属性赋新值将静默失败(非严格模式)或抛出
TypeError(严格模式) - 即使原属性原本是
writable: true,冻结后也无法再修改 - 该操作只影响当前层级的数据属性,不递归作用于嵌套对象的属性
访问器属性不受 writable 影响
如果属性是通过 get 和 set 定义的访问器属性,它的可写性不由 writable 控制,而是由 set 函数内部逻辑决定。冻结对象时:
-
writable字段对访问器属性无意义(描述符中本就不含该字段) -
configurable和enumerable会被设为false,但set仍可执行 - 例如:
obj.x = 10可能成功触发 setter,哪怕对象已冻结
检测与验证 writable 状态
不能仅靠 Object.isFrozen() 推断某个属性是否可写,需结合描述符检查:
立即学习“Java免费学习笔记(深入)”;
- 用
Object.getOwnPropertyDescriptor(obj, 'prop')查看具体writable值 - 若返回
{ writable: false, ... },说明该属性当前不可写 - 注意:即使
Object.isFrozen(obj) === true,也不能跳过描述符检查——因为冻结前可能已手动设为writable: true,而冻结只是将其改为false
冻结 ≠ 所有属性都“真正锁定”
常见误区是认为冻结后一切安全,但实际限制有边界:
- 嵌套对象未被冻结:如
obj.a = { b: 1 },冻结obj后,obj.a.b = 2依然有效 - Symbol 属性同样受冻结影响,但前提是它已是对象的自有属性
- 原型链上的属性不受影响,冻结只作用于对象自身


















