http://bubkoo.com/2014/01/23/...
原型中声明的属性和对象自带的属性
==原型 prototype 中声明的属性和对象自带的属性(其实这些属性也是在原型 prototype 中的)可以认为是带有 DontDelete 特性的,无法被删除==。例如:
//原型中声明的属性无法被删除
function C() { this.x = 42; }
C.prototype.x = 12;
var o = new C();
o.x; // 42, 构造函数中定义的o.x
delete o.x;
o.x; // 12, prototype中定义的o.x,即使再次执行delete o.x也不会被删除
//对象自带的属性无法被删除
var re = /abc/i;
delete re.ignoreCase;
re.ignoreCase; // true, ignoreCase无法删除
内置对象和DontDelete
些属性不能被删除的根本原因在于:==这些属性拥有内部属性 DontDelete==,该内部属性控制着该属性是否可以被删除。注意:内置对象的一些属性拥有内部属性 DontDelete,因此不能被删除; 特殊的 arguments 变量(活化对象的属性)拥有 DontDelete; 任何函数实例的 length (返回形参长度)属性也拥有 DontDelete。与函数 arguments 相关联的属性也拥有 DontDelete,同样不能被删除:
(function() {
//不能删除'arguments',因为有DontDelete
delete arguments; // false;
typeof arguments; // "object"
//也不能删除函数的'length',因为有DontDelete
function f() {};
delete f.length; // false;
typeof f.length; // "number"
}) ();
--------
(function(foo, bar) {
delete foo; // false
foo; // 1
delete bar; // false
bar; // "bah"
}) (1, "bah");
总结
下面是对于 JavaScript 中 delete 操作是如何工作的简短的总结:
- 变量和函数声明都是活化对象(Activation Object) 或全局对象(Global Object)的属性
- 属性拥有内部属性,其中 DontDelete 这个内部属性负责确定一个属性是否能够被删除
- 在全局或者函数代码中的变量和函数声明总是创建带有 DontDelete 特性的属性
- 函数参数总是活动对象的属性, 并且带有 DontDelete
- 在 Eval 代码中声明的变量和函数总是创建不带 DontDelete 特性 的属性
- 新的未声明的属性在生成时带空的内部属性,因此也不带 DontDelete 特性
- 永远不要相信宿主对象对 delete 操作做出的反应