在 JavaScript 中,需同时设置 writable 和 configurable 为 false 才能真正锁定属性为只读且不可删除;仅 writable: false 时属性仍可被 delete 或重新定义。

在 JavaScript 中,可以通过 Object.defineProperty() 设置属性描述符(descriptor),将属性设为只读且不可删除。关键在于将 writable 设为 false,同时将 configurable 也设为 false。
使用 data descriptor 控制读写与删除
data descriptor 是最常用的方式,适用于普通数据属性。它通过 writable 控制是否可修改值,configurable 控制是否可删除、重配置或改为 accessor descriptor。
-
writable: false→ 属性值不能被重新赋值(严格模式下赋值会报错,非严格模式静默失败) -
configurable: false→ 属性不能被delete删除,也不能再次调用defineProperty修改其描述符(除writable从true改为false外)
示例:
const obj = {};
Object.defineProperty(obj, 'PI', {
value: 3.14159,
writable: false,
configurable: false,
enumerable: true
});
console.log(obj.PI); // 3.14159
obj.PI = 3; // 无效(非严格模式)或 TypeError(严格模式)
delete obj.PI; // false(非严格模式),或 TypeError(严格模式)
注意:configurable 为 false 后不可逆
一旦将 configurable: false,该属性就永久锁定——不能再改回 true,也不能转成 getter/setter,甚至不能删掉再重建。
立即学习“Java免费学习笔记(深入)”;
- 试图再次 define 同名属性会抛出 TypeError(除非仅将
writable从true改为false) - 即使对象是可扩展的(extensible),该属性仍无法被删除或重定义
批量设置多个只读不可删属性
可用 Object.defineProperties() 一次性定义多个属性:
const constants = {};
Object.defineProperties(constants, {
MAX_RETRY: { value: 3, writable: false, configurable: false },
TIMEOUT: { value: 5000, writable: false, configurable: false },
ENV: { value: 'production', writable: false, configurable: false }
});
替代方案:冻结整个对象
若需让对象所有自有属性都只读且不可删,可使用 Object.freeze():
-
Object.freeze(obj)等价于对每个自有属性设writable: false和configurable: false - 它还会将
extensible设为false,阻止新增属性 - 注意:freeze 是浅冻结,嵌套对象仍可变(需递归冻结)
不复杂但容易忽略细节:只设 writable: false 而不设 configurable: false,属性仍能被 delete 或重新定义;两者必须同时为 false 才真正“锁定”。


















