此页面由社区从英文翻译而来。了解更多并加入 MDN Web Docs 社区。
delete 运算符
Baseline Widely available
This feature is well established and works across many devices and browser versions. It’s been available across browsers since 2015年7月.
delete 运算符用于删除对象的一个属性;如果该属性的值是一个对象,并且没有更多对该对象的引用,该属性所持有的对象最终会自动释放。
In this article
尝试一下
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.propertydelete 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; // 返回 falsefunction 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); // 返回 falsevar 会创建不可配置的属性,它不能用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> |