2010-02-14 58 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

相關問題