2010-02-14 35 views

回答

40

这是用奇怪的方式this绑定在JavaScript中的作品。

[].reverse 

是在空列表上的方法reverse。如果你调用它,通过一个:

[].reverse(); 
[]['reverse'](); 
([].reverse)(); 

然后将其与this绑定列表实例[]执行。但是,如果你脱离它:

x= [].reverse; 
x(); 

它没有this - 结合执行,在功能点到全球(window)对象,因此this,在JavaScript的最糟糕的,最误导的设计错误之一。

(x=[].reverse)() 

也在做分离。赋值运算符返回它传递的相同函数对象,因此它看起来没有任何作用,但它具有打破导致JavaScript绑定的有限特例的副作用this

所以你说:

Array.prototype.reverse.call(window) 

reverse,像许多其他Array.prototype方法,是由ECMAScript的定义为任何天然序列状物体上工作。它使用数字串键(最多为object.length)反转项目并返回该对象。所以它会返回传入的任何类型的对象,该类型具有length属性。

window有length属性,它对应于window.frames.length,所以调用此方法与this指着window将工作并返回window。从理论上讲它可能仍然会失败,因为:

  1. window允许是一个“宿主对象”,而不是“本地对象”;在这种情况下,您可以传递给其他原型方法的保证不一定适用;和
  2. 如果窗口实际上有帧/ iframe,它会尝试颠倒它们的顺序,这是行不通的,因为帧集合是只读的。

然而,在现有的浏览器在前一种情况下不工作,而后者静静地失败没有一个错误,所以你仍然得到===window行为也不例外。

+1

你碰巧知道为什么有人会把它编码?我的意思是,我明白为什么当然会出现这种情况,但为什么我会把它放在我的代码中?它实现了什么? – Pointy 2010-02-14 15:23:04

+3

绝对没有。它只是展示了JavaScript的许多意想不到的行为之一。如果我在真实的代码中发现这个,我会担心的! – bobince 2010-02-14 16:15:19

+2

这样做的一个可能的原因可能是检查是否有其他脚本与窗口对象(window = open('http://google.com/')')相混淆。 'var window =(x = []。reverse)();'可以在本地恢复它。 – silviot 2011-01-02 10:17:45

相关问题