为什么我无法删除使用Object.defineProperties定义的getter/setter?
两种getter定义方式删除行为差异的核心原因
两种场景的删除行为差异,本质来自JS对象属性描述符中configurable字段的默认取值不同。
首先明确两个场景的实际表现:
- 用对象字面量定义getter时,删除操作可正常生效:
var hello = { get num() { return 123; } } delete hello.num; // 返回值为true - 通过
Object.defineProperties手动定义访问器属性时,删除操作无法生效:var hello = {}; Object.defineProperties(hello, { num: { get() { return 123; } } }) delete hello.num; // 返回值为false
核心规则说明
JS中每个对象属性都绑定了一组描述符,用来管控属性的可修改、可枚举、可删除行为,其中configurable字段直接决定两个关键能力:
- 该属性是否可以被
delete操作移除 - 该属性的描述符本身是否可以被后续修改
两种定义方式下,configurable的默认取值完全不同:
- 用对象字面量形式(包括简写的getter/setter、普通键值对)创建的属性,默认
configurable: true、enumerable: true,属性可正常执行删除操作。 - 用
Object.defineProperty/Object.defineProperties手动创建属性时,所有没有在描述符里显式声明的字段,默认值都是false。上面的示例中只声明了get方法,没有指定configurable的取值,因此该属性的configurable默认为false,直接阻止了删除操作执行。
效果验证
如果在手动定义属性时显式将configurable设为true,访问器属性就可以和字面量定义的getter一样被正常删除:
var hello = {}; Object.defineProperties(hello, { num: { get() { return 123; }, configurable: true // 显式开启属性的可配置权限 } }) delete hello.num; // 此时删除操作返回值为true
这里需要澄清一个常见误区:访问器属性并不是天生不支持删除,只要configurable为真,无论通过哪种方式定义的getter/setter,都可以被正常移除。
补充说明:在非严格模式下,对
configurable: false的属性执行删除操作会静默失败,返回false;在严格模式下会直接抛出类型错误。
内容的提问来源于stack exchange,提问作者Dyn Pallomah
相关产品推荐
相关产品推荐

