Javascript教程:delete删除对象(4)
Firebug 困惑
那么,在Firebug中会发生什么呢?为什么在控制台中定义的变量可以被删除,难道与我们刚才了解到相反?很好,我先前说过,当涉及到的变量声明,Eval 代码(Eval code)有一个特殊的行为。在Eval 代码(Eval code)中声明的变量实际上没有创建DontDelete 特性。
eval(
'var foo = 1;'
);
foo;
// 1
delete
foo;
// true
typeof
foo;
// "undefined"confusion
同样,在函数代码(Function code)调用也是如此:
(
function
(){
eval(
'var foo = 1;'
);
foo;
// 1
delete
foo;
// true
typeof
foo;
// "undefined"
})();
这是Firebug的异常行为的要点,在控制台的所有文本似乎是作为Eval 代码(Eval code)来解析和执行的,而不是作为一个全局对象或函数对象,显然,任何声明的变量没有DontDelete特性,因此可以很容易地删除,应该意识到正常全局代码和Firebug控制台之间的分歧。
通过eval删除变量
这个有趣的eval
属性,连同ECMAScript 其它方面的技巧可以让我们删除不可删除的属性。在同一个执行上下文中,函数声明能覆盖同一名字的变量。
function
x(){ }
var
x;
typeof
x;
// "function"
注意函数如何获得优先权并覆盖同名变量(或者换句话说,可变对象相同的属性)。这是因为函数声明在变量声明之后实例化,并且可以覆盖它们。函数声明不仅取代了先前的属性值,而且也取代了属性特性。如果我们通过
eval
声明函数,该函数也应该替换自身的属性特性。既然在eval
内声明的变量没有DontDelete特性,那么实例化这个新函数应该从本质上消除属性中现有的DontDelete特性,是的这个属性可以删除(当然也就改变引用新创建函数的值)。
var
x = 1;
/* Can't delete, `x` has DontDelete */
delete
x;
// false
typeof
x;
// "number"
eval(
'function x(){}'
);
/* `x` property now references function, and should have no DontDelete */
typeof
x;
// "function"
delete
x;
// should be `true`
typeof
x;
// should be "undefined"
遗憾的是,这类欺骗在我尝试中并不总是运行,我可能丢失了一些东西,或者这种行为过于简单不足以引起注意。