delete 运算符
Baseline Widely available
This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.
delete
运算符用于删除对象的一个属性;如果该属性的值是一个对象,并且没有更多对该对象的引用,该属性所持有的对象最终会自动释放。
尝试一下
const Employee = { firstname: "Maria", lastname: "Sanchez", }; console.log(Employee.firstname); // Expected output: "Maria" delete Employee.firstname; console.log(Employee.firstname); // Expected output: undefined
语法
delete object.property delete object[property]
备注: 该语法允许在 delete
运算符之后使用多种类型的表达式,但只有上述形式才能产生有意义的行为。
参数
返回值
异常
TypeError
如果属性是自身不可配置的属性且处于严格模式中,则会抛出该异常。
ReferenceError
当
object
是super
时抛出。
描述
delete
运算符与其他像 typeof
这样的一元运算符具有相同的优先级。因此,它接受任何由更高优先级的运算符形成的表达式。然而,在严格模式下,以下形式会导致早期语法错误:
delete identifier; delete object.#privateProperty;
因为类自动处于严格模式,而私有属性只能在类体内合法引用,这意味着私有属性永远不能被删除。虽然 delete identifier
在 identifier
指的是全局对象的可配置属性时可能有效,但是你应该避免这种形式,而是用 globalThis
作为前缀。
虽然其他表达式是可以接受的,但是它们并不导致有意义的行为:
delete console.log(1); // 输出 1,返回 true,但是没有删除任何东西
delete
运算符从一个对象中删除一个给定的属性。在成功删除时,它将返回 true
,否则将返回 false
。不像一般人认为的那样(也许是由于其他编程语言,如 C++ 中的 delete),delete
操作符与直接释放内存没有关系。内存管理是通过破坏引用间接完成的。更多细节请参见内存管理页面。
但是,以下情况需要重点考虑:
- 如果你试图删除的属性不存在,那么
delete
将不会起任何作用,但仍会返回true
。 delete
只影响自身属性。如果对象的原型链上有一个与待删除属性同名的属性,那么删除属性之后,对象会使用原型链上的那个属性。- 不可配置的属性不能被移除。这意味着像
Math
、Array
、Object
这些内置对象的属性以及使用Object.defineProperty()
方法设置为不可配置的属性不能被删除。 - 删除包括函数参数内的变量永远不会奏效。
delete variable
会在严格模式下抛出SyntaxError
错误,非严格模式下不会有任何效果。
示例
使用 delete
备注: 以下示例使用了仅非严格模式下的功能,如隐式创建全局变量和删除标识符,这在严格模式下是禁止的。
// 在全局作用域创建 empCount 属性 // 因为我们使用了 var,它会标记为不可配置 var empCount = 43; // 在全局作用域创建 adminName 属性 // 因为没有使用 var,它会标记为可配置 adminName = "xyz"; EmployeeDetails = { name: "xyz", age: 5, designation: "Developer", }; // delete 可用于删除对象的属性 delete EmployeeDetails.name; // 返回 true // 甚至属性不存在,它也会返回 "true" delete EmployeeDetails.salary; // 返回 true // EmployeeDetails 是全局作用域的一个属性。 delete EmployeeDetails; // 返回 true // 相反,empCount 是不可配置的, // 因为创建它时使用了 var。 delete empCount; // 返回 false // adminName 是全局作用域的一个属性。 // 因为它不是用 var 创建的,所以可以删除。 // 因此,它是可配置的。 delete adminName; // 返回 true // delete 对内建静态属性不起作用 // 这些属性是不可配置的 delete Math.PI; // 返回 false function f() { var z = 44; // delete 对局部变量名不起作用 delete z; // 返回 false }
delete 和原型链
在下面的示例中,我们删除一个对象的自有属性,而原型链上具有相同名称的属性可用:
function Foo() { this.bar = 10; } Foo.prototype.bar = 42; var foo = new Foo(); // foo.bar 指代了自身属性 console.log(foo.bar); // 10 // 删除 foo 对象的自身属性 delete foo.bar; // 返回 true // foo.bar 仍然在原型链上可用。 console.log(foo.bar); //42 // 从原型上删除属性 delete Foo.prototype.bar; // 返回 true // 由于已删除“bar”属性,因此不能再从 Foo 继承它。 console.log(foo.bar); //undefined
删除数组元素
当你删除一个数组元素时,数组的长度(length
)不受影响。即便你删除了数组的最后一个元素也是如此。
当用 delete
运算符删除一个数组元素时,被删除的元素已经不再属于该数组。下面的例子中用 delete
删除了 trees[3]
。
const trees = ["redwood", "bay", "cedar", "oak", "maple"]; delete trees[3]; console.log(3 in trees); // false
以上操作创建了一个稀疏数组,如果你想让一个数组元素继续存在,但是其值是 undefined
,那么可以将 undefined
赋值给这个元素而不是使用 delete
。下面的例子中,trees[3]
被赋值为 undefined
,但该数组元素仍然存在。
const trees = ["redwood", "bay", "cedar", "oak", "maple"]; trees[3] = undefined; console.log(3 in trees); // true
如果你想通过改变数组的内容来移除一个数组元素,请使用 splice()
方法。在下面的例子中,通过使用 splice()
,将 trees[3]
从数组中移除。
const trees = ["redwood", "bay", "cedar", "oak", "maple"]; trees.splice(3, 1); console.log(trees); // ["redwood", "bay", "cedar", "maple"]
删除不可配置属性
当一个属性被标记为不可配置时,delete
不会有任何效果,并将返回 false
。在严格模式下,会抛出 TypeError
。
const Employee = {}; Object.defineProperty(Employee, "name", { configurable: false }); console.log(delete Employee.name); // 返回 false
var
会创建不可配置的属性,它不能用 delete
运算符删除。
// 由于“nameOther”是使用 var 关键字声明的, // 它被标记为不可配置的 var nameOther = "XYZ"; // 我们可以通过以下代码访问这个全局属性: Object.getOwnPropertyDescriptor(globalThis, "nameOther"); // { // value: "XYZ", // writable: true, // enumerable: true, // configurable: false // } delete globalThis.nameOther; // 返回 false
在严格模式下,会抛出异常。
删除全局属性
如果一个全局属性是可配置的(例如,通过直接的属性赋值),它可以被删除,随后将它们作为全局变量的引用将产生 ReferenceError
。
globalThis.globalVar = 1; console.log(globalVar); // 1 // 在非严格模式下,也可以使用 `delete globalVar` delete globalThis.globalVar; console.log(globalVar); // ReferenceError: globalVar is not defined
规范
Specification |
---|
ECMAScript® 2026 Language Specification # sec-delete-operator |