删除
**delete
** 运算符从对象中删除属性。如果属性的值是对象,并且没有对该对象的更多引用,则该属性持有的对象最终将自动释放。
试试
语法
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);
// Logs 1, returns true, but nothing deleted
delete
运算符从对象中删除给定的属性。如果成功删除,它将返回 true
,否则将返回 false
。与普遍的看法相反(可能是由于其他编程语言,如C++ 中的 delete),delete
运算符与直接释放内存**无关**。内存管理是通过断开引用间接完成的。有关更多详细信息,请参阅内存管理页面。
务必考虑以下场景
- 如果要删除的属性不存在,
delete
将没有任何效果,并将返回true
。 delete
仅对自身属性有效。如果对象原型链上存在相同名称的属性,那么在删除后,该对象将使用原型链上的属性。- 不可配置的属性不能删除。这包括内置对象的属性,如
Math
、Array
、Object
以及使用Object.defineProperty()
等方法创建为不可配置的属性。 - 无法删除变量,包括函数参数。
delete variable
将在严格模式下抛出SyntaxError
,并且在非严格模式下没有任何效果。
示例
使用 delete
**注意:**以下示例使用仅非严格模式功能,如隐式创建全局变量和删除标识符,这些在严格模式下是被禁止的。
// Creates the property empCount on the global scope.
// Since we are using var, this is marked as non-configurable.
var empCount = 43;
// Creates the property EmployeeDetails on the global scope.
// Since it was defined without "var", it is marked configurable.
EmployeeDetails = {
name: "xyz",
age: 5,
designation: "Developer",
};
// delete can be used to remove properties from objects.
delete EmployeeDetails.name; // returns true
// Even when the property does not exist, delete returns "true".
delete EmployeeDetails.salary; // returns true
// EmployeeDetails is a property of the global scope.
delete EmployeeDetails; // returns true
// On the contrary, empCount is not configurable
// since var was used.
delete empCount; // returns false
// delete also does not affect built-in static properties
// that are non-configurable.
delete Math.PI; // returns false
function f() {
var z = 44;
// delete doesn't affect local variable names
delete z; // returns false
}
delete 和原型链
在以下示例中,我们删除了对象的自身属性,同时原型链上有一个同名属性
function Foo() {
this.bar = 10;
}
Foo.prototype.bar = 42;
const foo = new Foo();
// foo.bar is associated with the
// own property.
console.log(foo.bar); // 10
// Delete the own property within the
// foo object.
delete foo.bar; // returns true
// foo.bar is still available in the
// prototype chain.
console.log(foo.bar); // 42
// Delete the property on the prototype.
delete Foo.prototype.bar; // returns true
// The "bar" property can no longer be
// inherited from Foo since it has been
// deleted.
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
值,而不是 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); // returns false
var
创建不可配置的属性,这些属性无法使用 delete
运算符删除
// Since "nameOther" is added using with the
// var keyword, it is marked as non-configurable
var nameOther = "XYZ";
// We can access this global property using:
Object.getOwnPropertyDescriptor(globalThis, "nameOther");
// {
// value: "XYZ",
// writable: true,
// enumerable: true,
// configurable: false
// }
delete globalThis.nameOther; // return false
在严格模式下,这将引发异常。
删除全局属性
如果全局属性是可配置的(例如,通过直接属性赋值),则可以删除它,并且对它们作为全局变量的后续引用将产生 ReferenceError
。
globalThis.globalVar = 1;
console.log(globalVar); // 1
// In non-strict mode, you can use `delete globalVar` as well
delete globalThis.globalVar;
console.log(globalVar); // ReferenceError: globalVar is not defined
规范
规范 |
---|
ECMAScript 语言规范 # sec-delete-operator |
浏览器兼容性
BCD 表格仅在浏览器中加载