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 

语法

js
delete object.property delete object[property] 

备注: 该语法允许在 delete 运算符之后使用多种类型的表达式,但只有上述形式才能产生有意义的行为。

参数

object

对象的名称,或计算结果为对象的表达式。

property

要删除的属性。

返回值

对于大多数情况都是 true;如果属性是一个自身不可配置的属性,在这种情况下,非严格模式返回 false

异常

TypeError

如果属性是自身不可配置的属性且处于严格模式中,则会抛出该异常。

ReferenceError

objectsuper 时抛出。

描述

delete 运算符与其他像 typeof 这样的一元运算符具有相同的优先级。因此,它接受任何由更高优先级的运算符形成的表达式。然而,在严格模式下,以下形式会导致早期语法错误:

js
delete identifier; delete object.#privateProperty; 

因为自动处于严格模式,而私有属性只能在类体内合法引用,这意味着私有属性永远不能被删除。虽然 delete identifieridentifier 指的是全局对象的可配置属性时可能有效,但是你应该避免这种形式,而是用 globalThis 作为前缀。

虽然其他表达式是可以接受的,但是它们并不导致有意义的行为:

js
delete console.log(1); // 输出 1,返回 true,但是没有删除任何东西 

delete 运算符从一个对象中删除一个给定的属性。在成功删除时,它将返回 true,否则将返回 false。不像一般人认为的那样(也许是由于其他编程语言,如 C++ 中的 delete),delete 操作符与直接释放内存没有关系。内存管理是通过破坏引用间接完成的。更多细节请参见内存管理页面。

但是,以下情况需要重点考虑:

  • 如果你试图删除的属性不存在,那么 delete 将不会起任何作用,但仍会返回 true
  • delete 只影响自身属性。如果对象的原型链上有一个与待删除属性同名的属性,那么删除属性之后,对象会使用原型链上的那个属性。
  • 不可配置的属性不能被移除。这意味着像 MathArrayObject 这些内置对象的属性以及使用 Object.defineProperty() 方法设置为不可配置的属性不能被删除。
  • 删除包括函数参数内的变量永远不会奏效。delete variable 会在严格模式下抛出 SyntaxError 错误,非严格模式下不会有任何效果。
    • 任何使用 var 声明的属性不能从全局作用域或函数的作用域中删除,因为即使它们可能附加到全局对象上,它们也是不可配置的。
    • 任何使用 letconst 声明的属性不能够从它被声明的作用域中删除,因为它们没有附加到任何对象上。

示例

使用 delete

备注: 以下示例使用了仅非严格模式下的功能,如隐式创建全局变量和删除标识符,这在严格模式下是禁止的。

js
// 在全局作用域创建 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 和原型链

在下面的示例中,我们删除一个对象的自有属性,而原型链上具有相同名称的属性可用:

js
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]

js
const trees = ["redwood", "bay", "cedar", "oak", "maple"]; delete trees[3]; console.log(3 in trees); // false 

以上操作创建了一个稀疏数组,如果你想让一个数组元素继续存在,但是其值是 undefined,那么可以将 undefined 赋值给这个元素而不是使用 delete。下面的例子中,trees[3] 被赋值为 undefined,但该数组元素仍然存在。

js
const trees = ["redwood", "bay", "cedar", "oak", "maple"]; trees[3] = undefined; console.log(3 in trees); // true 

如果你想通过改变数组的内容来移除一个数组元素,请使用 splice() 方法。在下面的例子中,通过使用 splice(),将 trees[3] 从数组中移除。

js
const trees = ["redwood", "bay", "cedar", "oak", "maple"]; trees.splice(3, 1); console.log(trees); // ["redwood", "bay", "cedar", "maple"] 

删除不可配置属性

当一个属性被标记为不可配置时,delete 不会有任何效果,并将返回 false。在严格模式下,会抛出 TypeError

js
const Employee = {}; Object.defineProperty(Employee, "name", { configurable: false }); console.log(delete Employee.name); // 返回 false 

var 会创建不可配置的属性,它不能用 delete 运算符删除。

js
// 由于“nameOther”是使用 var 关键字声明的, // 它被标记为不可配置的 var nameOther = "XYZ"; // 我们可以通过以下代码访问这个全局属性: Object.getOwnPropertyDescriptor(globalThis, "nameOther"); // { // value: "XYZ", // writable: true, // enumerable: true, // configurable: false // } delete globalThis.nameOther; // 返回 false 

在严格模式下,会抛出异常。

删除全局属性

如果一个全局属性是可配置的(例如,通过直接的属性赋值),它可以被删除,随后将它们作为全局变量的引用将产生 ReferenceError

js
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

浏览器兼容性

参见