2009-12-07 46 views
1

爲什麼下面的代碼不工作?document.getElementsByTagName的本地副本

var f = document.getElementsByTagName; 
var x = f('div'); 

我在Chrome中獲得「TypeError:Illegal invocation」,在Safari中出現「TypeError:Type error」。我沒有在Firefox中遇到錯誤,但它不起作用。我還沒有在IE或Opera中進行過測試。

+0

一個跟進的問題應該是,爲什麼不'document.getElementsByTagName.call(文件,「格」)'在IE瀏覽器的工作? – 2009-12-07 01:36:45

+0

哪個IE?它在IE8中正常工作。 – 2009-12-07 20:17:44

+0

@Peter Hansen:IE <8。 8 IE瀏覽器hosed方法懸掛DOM元素(COM對象)之前。試試看:'typeof document.getElementById'返回''object「'。 – 2009-12-08 01:13:42

回答

7

在Javascript中,沒有像「綁定方法」這樣的東西(借用Python的術語,我希望您已經知道,或者解釋可能需要更長一些)。當您抓取對「document.getElementsByTagName」的引用時,您只是獲得對與文檔對象關聯的函數而不是方法的引用。當你調用它時,「this」被設置爲窗口,而不是文檔,所以它不起作用。

從技術上講這樣做會得到你想要的東西,但你或許可以看到它是毫無意義的:

var x = f.call(document, 'div') 

(這是沒有意義的,因爲它的可讀性和速度不如調用document.getElementsByTagName()使用。閉包同樣是沒有意義的。)

+1

非常有意義。謝謝。 – Brian 2009-12-07 02:01:30

0

試試這個:

function f(divName){ 
    return document.getElementById(divName); 
} 

var x = f('div'); 

您試圖調用一個函數,使用括號。問題是'f',在你的代碼中是一個變量,而不是一個函數。

2

因爲在JavaScript中,從方法上,他們是所謂的對象得到他們this,並調用存儲在一個單獨的變量方法使得該this是全球範圍內(或window,在瀏覽器)。這應該工作:

var f function() 
{ 
    return document.getElementsByTagName.apply(
     document 
     , arguments 
    ); 
} 
var x = f('div'); 
+0

IE不支持這一點。 – 2009-12-07 01:37:46

+0

你可以這樣做,沒有'申請'的原因有兩個:1.'getElementsByTagName'只接收*一個參數*,2.因爲你正在調用'document'對象上的函數,上下文將被隱式設置*,沒有理由再次申請。 – CMS 2009-12-07 01:44:16

0

原因是getElementsByTagName需要在對象上調用。你可以說在函數定義裏面,它使用this來找出在哪個元素中尋找標籤。當你複製函數然後調用它時,它會被賦予一個新的作用域,這意味着this沒有指向一個不同的對象。爲了呼籲文檔的功能,試試這個:

var f = document.getElementsByTagName; 
var x = f.call(document, "pre"); 
alert(x[0]);