解析JavaScript中delete操作符不能删除的对象
本文深入解析JavaScript中delete操作符无法删除特定对象的原因。从ES3的DontDelete特性到ES5的[[Configurable]]属性,详细列举了arguments、var声明变量、函数声明、内置构造器原型等不可删除的情况,并探讨了严格模式下的异常处理及原型链继承对delete行为的影响。
ES3中DontDelete特性与不可删除对象
在ES3规范中,关于delete操作符的定义出现在8.6.2.5及11.4.1章节,具体内容如下


存在一些关键信息
1、从实现层面看,delete操作符会调用引擎内部的[[Delete]]方法
2、[[Delete]]方法在8.6.2章节中进行定义

3、如果待删除的属性具有DontDelete特性,delete操作将直接返回false
搜索“DontDelete”关键字,会发现大量具有该特性的属性无法被删除,例如以下情况
1、激活对象中的arguments对象 (10.1.6)
代码如下:
function func() {
delete arguments;
alert(arguments);
}
func(1);2、变量声明 (10.2.1)
代码如下:
var a = 10;
delete a;
alert(a); // 10这一点在许多JavaScript书籍中均有提及,即无法通过delete删除使用var声明的变量。
3、函数声明
代码如下:
function func() {}
delete func;
alert(func); // func code4、函数的length属性
代码如下:
function func(a, b) {}
delete func.length;
alert(func.length); // 25、部分常量(NaN、Infinity、undefined)
代码如下:
delete NaN; // false
delete Infinity; // false
delete undefined; // false6、内置构造器的prototype属性
代码如下:
delete Object.prototype; // false
delete Function.prototype; // false
delete Array.prototype; // false
delete ExpReg.prototype; // false
delete Date.prototype; // false
delete Error.prototype; // false
delete Number.prototype; // false
delete Boolean.prototype; // false
delete String.prototype; // false7、数组和字符串的length属性
代码如下:
var arr = [], str = 'hello';
delete arr.length; // false
delete str.length; // false8、Math对象的属性(Math.E、Math.LN10、Math.LN2、Math.LOG2E、Math.LOG10E、Math.PI、Math.SQRT1_2、Math.SQRT2)
代码如下:
delete Math.E; // false
... 9、正则对象的属性(source、global、ignoreCase、multiline、lastIndex)
代码如下:
var reg = /ss/;
delete reg.source; // false
... ES5中[[Configurable]]属性与严格模式
ES5与ES3存在差异,ES5中不再使用“DontDelete”这一概念,转而引入[[Configurable]]属性(8.6.1)。

如果该属性的[[Configurable]]值为false,则无法执行delete操作,上述列举的9种情况在ES5中均被描述为[[Configurable]]为false。
ES5新增的Object.defineProperty方法允许显式定义对象的Configurable属性,示例如下
代码如下:
var obj = {name: 'John'};
Object.defineProperty(obj, "key", {
configurable: false,
value: "static"
});
delete obj.name; // true
delete obj.key // false对象obj包含name和key两个属性。name属性可以被delete删除,而key属性由于被显式设置为不可配置,因此无法删除。
此外,在ES5严格模式下,尝试delete Configurable为false的对象属性会直接抛出异常。例如
代码如下:
"use strict";
delete Object.prototype;在Firefox浏览器控制台中会报错如下

原型链继承对delete操作的影响
除了内置对象的部分方法或属性不可删除外,自定义对象中也存在无法删除的情况。例如,delete操作无法删除从原型链继承的属性
代码如下:
function Person() {}
Person.prototype.name = 'John Backus';
var p = new Person();
delete p.name;
console.log(p.name); // 仍然输出 John Backus如果实例对象this和原型prototype上同时存在name属性,执行delete后,实例上的属性被移除,原型上的属性便会显现出来
代码如下:
function Person() {
this.name = 'John Backus';
}
Person.prototype.name = 'John Resig';
var p = new Person();
console.log(p.name); // John Backus
delete p.name;
console.log(p.name); // John Resig, 来自原型如果确实需要删除原型上的name属性,只能采取以下方法
代码如下:
delete Person.prototype.name总结如下:
总结:delete操作的限制与原因
1、内置对象的属性及方法大多数无法通过delete删除(尽管部分方法如isNaN、parseInt可以删除)
2、对象从原型继承的属性和方法无法通过delete删除
其原因相对简单
1、内置对象的属性及方法大多数不可删除,这是为了保护语言的核心API。如果这些核心API被删除,JavaScript引擎将基本失效。例如delete Object.prototype会导致严重后果。
2、对象从原型继承的属性和方法不可删除,这是为了保护原型链的完整性。否则,“如果类A的对象删除了原型上的属性,那么所有继承自A的实例都将丢失该属性”,这将导致不可预知的错误。
JS语法错误会阻止加载吗?区分SyntaxError与资源加载失败
2026-11-05 16:08:46
JavaScript常见SyntaxError语法错误排查与修复方法
2026-11-05 13:58:44
JS中slice、substring和substr截取字符串的区别
2026-11-05 13:43:47
JS 转 TS 手动迁移最佳实践:从配置 tsconfig 到消除 any 类型
2026-11-05 11:53:32
为什么JS数组push后得到的是数字而不是数组?
2026-11-05 09:59:18
