delete运算符在对象已定义时是否始终返回true?为何删除不存在的键不返回false
关于JavaScript delete运算符返回值的疑问解答
嘿,这个问题问到点子上了,很多刚接触JS的开发者都会对delete的返回逻辑感到困惑,我来给你拆解清楚:
首先明确delete的返回规则
delete运算符的返回值并不是简单的“删除成功/失败”,而是遵循以下规则:
- 返回true的情况:
- 删除对象自身的可配置属性(不管属性原本存在与否——如果属性不存在,delete相当于执行了一个无意义的操作,但依然返回true);
- 删除对象原型链上的可配置属性(不过这种场景很少见)。
- 返回false的情况(非严格模式):
- 要删除的属性是对象自身的,但不可配置(比如用
Object.defineProperty设置了configurable: false); - 试图删除一个变量、函数声明,或者全局对象的不可配置属性(比如
window的某些内置属性)。
- 要删除的属性是对象自身的,但不可配置(比如用
- 严格模式下的特殊情况:
如果尝试删除不可配置的属性、变量或函数,会直接抛出TypeError,而不是返回false。
解释你的测试用例
- 第一个代码
console.log( delete ({a: true}['a']) );:这里a是对象自身的可配置属性,删除成功,所以返回true; - 第二个代码
console.log( delete ({a: true}['b']) );:b不存在于对象中,根据规则,这种情况delete依然返回true——因为规范里定义,当目标属性不存在时,delete操作不会失败,而是返回true。
回答你的核心疑问
当对象已定义时,delete运算符是否总是返回true?
当然不是!举几个反例你就明白了:
- 删除不可配置的属性:
const obj = {}; // 定义一个不可配置的属性a Object.defineProperty(obj, 'a', { value: true, configurable: false }); console.log(delete obj.a); // 非严格模式下输出false,严格模式下报错
- 删除变量声明:
let testVar = 100; console.log(delete testVar); // 输出false,严格模式下报错
关于你的替代写法
你用('b' in v) && delete v['b']的写法是完全正确的——如果你需要先判断属性存在,再执行删除操作,这个表达式能准确返回“属性存在且删除成功”的结果(如果属性不存在,整个表达式返回false;如果属性存在但不可配置,delete返回false,表达式也会返回false)。
内容的提问来源于stack exchange,提问作者Alexander Mills
相关产品推荐
相关产品推荐

