Javascript教程:delete删除对象(6)
IE bugs
整个章节仅仅为了IE中的bug,想不到吧!
在IE浏览器中(至少是IE6-IE8),下面的表达式抛出错误(在全局代码中执行):
this
.x = 1;
delete
x;
// TypeError: Object doesn't support this action
这个也是一样,但异常不同,只是更有趣:
var
x = 1;
delete
this
.x;
// TypeError: Cannot delete 'this.x'
IE中看起来好像在全局代码中声明变量不能在全局对象中创建属性。通过赋值创建属性(
this.x = 1
),然后通过delete
删除x将抛出错误。通过声明创建创建属性(var x = 1
),然后通过delete this.x
删除将抛出另外一个错误。
但这还没完。实际上通过明确的赋值创建的属性在删除时始终引发错误。这不仅是一个错误,而且创建的属性似乎设置了DontDelete特性,这当然不应该有:
this
.x = 1;
delete
this
.x;
// TypeError: Object doesn't support this action
typeof
x;
// "number" (still exists, wasn't deleted as it should have been!)
delete
x;
// TypeError: Object doesn't support this action
typeof
x;
// "number" (wasn't deleted again)
与我们思考的相反,未声明的变量(应该在一个全局对象中创建属性)在IE中创建了可删除属性。
x = 1;
delete
x;
// true
typeof
x;
// "undefined"
但是,如果您尝试通过“this”引用在全局代码中删除它(
delete
this.x ),一个熟悉的错误弹出:
x = 1;
delete
this
.x;
// TypeError: Cannot delete 'this.x'
如果我们总结这些行为,从全局代码中
delete this.x
似乎是不成功的。当涉及到的属性是通过显式声明(this.x = 1
)来创建的,delete
将抛出一个错误。当属性是通过未声明的赋值(x = 1
)或声明(var x = 1
)来创建属性时,delete
将抛出另一个错误。
另一方面,当涉及到的属性是通过显式声明(this.x = 1
)创建时,delete
x 抛出错误。如果一个属性是通过声明(var x = 1
)来创建的,删除根本不会发生,并返回正确的false。如果属性是通过未声明的方式(x = 1
)创建,删除操作将按预期进行。
去年九月我正在思考这个问题,Garrett Smith 建议“在IE中全局可变对象作为一个JScript对象,全局对象有宿主执行”。Garrett 引用Eric Lippert’s blog entry ,我们可以通过一些测试验证这些理论。请注意,this
和window
似乎引用同一对象(如果我们相信“===
”运算符),但可变对象(在一个声明的函数中的对象)不同于这一点。
/* in Global code */
function
getBase(){
return
this
; }
getBase() ===
this
.getBase();
// false
this
.getBase() ===
this
.getBase();
// true
window.getBase() ===
this
.getBase();
// true
7.
window.getBase() === getBase();
// false