delete
操作符用来删除一个对象的属性。
语法
delete expression
expression 应该是一个对象的属性引用,例如:
delete object.property delete object['property']
如果 expression 的计算结果不是一个对象的属性引用,那么,delete不会起任何作用。
参数
objectName
- 对象名.
property
- 需要删除的属性.
返回值
在严格模式中,如果属性是一个不可配置(non-configurable)属性,删除时会抛出异常,非严格模式下返回 false
。其他情况都返回 true
。
描述
delete 操作符与直接释放内存(只能通过解除引用来间接释放)没有关系。可查看内存管理页面。
你可以使用 delete
操作符来删除一个隐式声明的全局变量,也就是没有使用 var
定义的全局变量.全局变量其实是global对象(window)的属性.
如果 delete
操作符删除成功,则被删除的属性将从所属的对象上彻底消失。然后,如果该对象的原型链上有一个同名属性,则该对象会从原型链上继承该同名属性。
Temporal dead zone
在ECMAScript 6中,通过 const 或 let
声明指定的 "temporal dead zone" (TDZ) 对 delete 操作符也会起作用。因此,下面的代码将会抛出 ReferenceError
。
function foo(){ delete x; let x; } function bar() { delete y; const y; }
一些对象的属性不能被delete. ECMA 262 规范中把这些属性标记为 DontDelete.
x = 42; // 隐式声明的全局变量 var y = 43; // 显式声明的全局变量 myobj = { h: 4, k: 5 } // 隐式声明的全局变量可以被删除 delete x; // 返回 true // 显式声明的全局变量不能被删除,该属性不可配置(not configurable) delete y; // 返回 false //内置对象的内置属性不能被删除 delete Math.PI; // 返回 false //用户定义的属性可以被删除 delete myobj.h; // 返回 true // myobj 是全局对象的属性,而不是变量 //因此可以被删除 delete myobj; // 返回 true function f() { var z = 44; // delete doesn't affect local variable names delete z; // returns false }
你不能删除一个对象从原型继承而来的属性(不过你可以从原型上直接删掉它).
function Foo(){} Foo.prototype.bar = 42; var foo = new Foo(); // 无效的操作 delete foo.bar; // logs 42,继承的属性 console.log(foo.bar); // 直接删除原型上的属性 delete Foo.prototype.bar; // logs "undefined",已经没有继承的属性 console.log(foo.bar);
删除数组元素
当你删除一个数组元素时,数组的 length 属性并不会变小。例如,如果你删除了a[3], a[4]仍然是a[4], a[3]成为undefined. 即便你删除了最后一个元素也是如此 (delete a[a.length-1]
).
当用 delete
操作符删除一个数组元素时,被删除的元素已经完全不属于该数组。下面的例子中, trees[3] 被使用delete彻底删除
。
var trees = ["redwood","bay","cedar","oak","maple"]; delete trees[3]; if (3 in trees) { // 这里不会被执行 }
如果你想让一个数组元素的值变为 undefined
而不是删除它,可以使用 undefined
给其
赋值而不是使用 delete
操作符。下面的例子中,trees[3] 被赋值为undefined
,但该元素仍然存在。
var trees = ["redwood","bay","cedar","oak","maple"]; trees[3]=undefined; if (3 in trees) { // 这里会被执行 }
规范
Specification | Status | Comment |
---|---|---|
ECMAScript 2017 Draft (ECMA-262) The delete Operator |
Draft | |
ECMAScript 2015 (6th Edition, ECMA-262) The delete Operator |
Standard | |
ECMAScript 5.1 (ECMA-262) The delete Operator |
Standard | |
ECMAScript 1st Edition (ECMA-262) The delete Operator |
Standard | Initial definition. Implemented in JavaScript 1.2. |
浏览器兼容性
Feature | Chrome | Firefox (Gecko) | Internet Explorer | Opera | Safari |
---|---|---|---|---|---|
Basic support | (Yes) | (Yes) | (Yes) | (Yes) | (Yes) |
Temporal dead zone | ? | 36 (36) | ? | ? | ? |
Feature | Android | Chrome for Android | Firefox Mobile (Gecko) | IE Mobile | Opera Mobile | Safari Mobile |
---|---|---|---|---|---|---|
Basic support | (Yes) | (Yes) | (Yes) | (Yes) | (Yes) | (Yes) |
Temporal dead zone | ? | ? | 36.0 (36) | ? | ? | ? |
跨浏览器问题
虽然 ECMAScript 规定了对象的遍历顺序是由对象定义时属性的书写顺序决定的。(译者注:ES5已经对遍历机制做了调整,重新规定:属性遍历的顺序是没有被规定的), 大部分浏览器都依照这个规定,先添加的属性先被遍历(除了从原型上继承的属性)(译者注:Chrome和Opera已经遵循了ES5的新规定,具体请看)。但是,在 Internet Explorer 中,使用 delete
删除一个属性后,奇怪的事情发生了,如果被删除的属性重新被添加,那么遍历时,该属性的顺序会是上次删除前的那个位置所应该有的顺序,而不是出现在遍历的最后一个。
所以,如果你想让对象的遍历顺序兼容所有的浏览器,那么你可以使用两个数组来模拟 (一个做为keys,一个做为 values), 或者建立一个由单一属性的对象组成的数组,等。