当原型上属性的writable: false时,实例赋值行为取决于自身是否已有该属性:若无,则非严格模式静默失败、严格模式报错;若有,则按实例描述符处理,原型writable失效。

当属性的 writable: false 设置在原型对象上时,它不会直接“锁住”实例对象的同名属性,但会显著改变通过 = 赋值操作的行为——关键在于:赋值时是否会在实例上创建新属性,还是试图修改原型上的只读属性。
原型上 writable: false 会阻止实例“覆盖式赋值”
如果实例自身没有该属性,而原型链上存在一个 writable: false 的数据属性(data descriptor),那么执行 obj.prop = newValue 时:
- 非严格模式下:静默失败,
obj上不新增属性,原型上的值也不变,obj.prop读取仍返回原型值 - 严格模式下:立即抛出
TypeError: Cannot assign to read only property 'prop' -
obj.hasOwnProperty('prop')仍为false,说明赋值未生效,也未在实例上创建副本
实例已有属性时,原型的 writable 不再起作用
一旦实例对象自身拥有同名属性(无论怎么来的),后续对该属性的赋值就完全由实例自身的描述符决定,原型上的 writable 不再参与判断。
- 例如:
obj.prop = 1后,obj.hasOwnProperty('prop')变为true - 此时即使原型上也有
prop且writable: false,也不会影响对实例属性的写入 - 读取时仍优先取实例属性,原型属性被屏蔽(shadowed)
与 accessor descriptor(getter/setter)的区别
如果原型上的同名属性是访问器描述符(即定义了 get 或 set),那么 writable 字段会被忽略——JS 引擎只看 set 函数是否存在。
立即学习“Java免费学习笔记(深入)”;
- 有
set:赋值会触发该 setter,与writable无关 - 无
set:赋值行为等同于writable: false的数据属性(报错或静默) - 注意:不能靠设
writable: true让只读 getter 变可写,必须提供有效的set
实际调试建议
遇到赋值无效时,不要只查实例本身,要沿原型链检查:
- 用
Object.getOwnPropertyDescriptor(Object.getPrototypeOf(obj), 'prop')查原型上的描述符 - 用
obj.hasOwnProperty('prop')确认属性是否在实例上 - 用
Object.getPrototypeOf(obj).prop直接读原型值,排除屏蔽干扰 - 严格模式下打开控制台,错误提示会明确指出是只读属性问题


















