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® 2025 Language Specification
# sec-delete-operator

浏览器兼容性

Report problems with this compatibility data on GitHub
desktopmobileserver
Chrome
Edge
Firefox
Opera
Safari
Chrome Android
Firefox for Android
Opera Android
Safari on iOS
Samsung Internet
WebView Android
WebView on iOS
Deno
Node.js
delete

Legend

Tip: you can click/tap on a cell for more information.

Full support
Full support

参见