为什么要删除窗口的重写属性?

时间:2012-04-25 16:13:55

标签: javascript

delete运算符从对象中删除属性。如果我在window上设置了一个属性,我可以将其删除:

window.myProp = 10;
delete window.myProp;

作为the article我经常在涉及delete运算符状态的行为时引用其他人,这是因为属性赋值不设置DontDelete属性(而不是{变量声明,确实如此)。

该文章还指出了以下内容(重点补充):

  

请注意,在属性创建期间,属性是   确定(即没有设定)。 以后的作业不会修改   现有财产的属性。理解这一点很重要   区别。

请注意,为什么我可以覆盖窗口的现有属性alert,然后将其删除为返回原始值?我错过了一些明显的东西吗我很少使用delete运算符,所以很可能就是这种情况。

例如:

window.alert = function() {};
alert("Hi!"); //Nothing happens

delete window.alert;
alert("Hello?"); //Alerts 'Hello?'

这里有一个fiddle来证明这一点(仅在Chome进行过测试,非常确定IE不会以这种方式运行,但现在除了Chrome之外无法访问任何内容)。

2 个答案:

答案 0 :(得分:9)

在Chrome中,window.alert函数是DOMWindow类的原型的一部分,它不是window本身的属性。

因此,当您覆盖window.alert时,您正在向window添加 new 属性,但原型中的版本仍然存在,但是已隐藏。

delete window.alert重新暴露原型中的函数时。

这是一些控制台输出,显示该函数在原型中:

> window.constructor.prototype
DOMWindow

> window.constructor.prototype.alert
function alert() { [native code] }

Firefox的行为类似,尽管有不同的类名。

答案 1 :(得分:2)

这是预期的行为,称为阴影。它允许您提供自定义功能,而不会消除超类的功能。删除方法时,将删除自定义方法,从原型中显示原始方法。

你越接受继承并理解原型的工作方式,你就越会发现自己看到人们这样做的实例。

很好的问题。根据我的经验,这不是大多数JavaScript开发人员经常探索的领域。如果不是这种类型的东西,那么扩展或覆盖JavaScript基础对象的核心功能的许多polyfill是不可能的。