2012-05-24 73 views
50

例如,如果我這樣做:爲什麼JavaScript中某些函數調用被稱爲「非法調用」?

var q = document.querySelectorAll; 

q('body'); 

我在Chrome中得到一個「非法調用」錯誤。我想不出爲什麼這是必要的。首先,所有本機代碼功能都不是這種情況。其實我可以這樣做:

var o = Object; // which is a native code function 

var x = new o(); 

而且一切正常。特別是我在處理文檔和控制檯時發現了這個問題。有什麼想法嗎?

+0

[爲什麼不能爲document.getElementById()設置別名?](http://stackoverflow.com/questions/10723496/why-cant-one-set-an-alias-to- document-getelementbyid) – Quentin

+1

可能重複[JavaScript函數別名似乎不工作](http://stackoverflow.com/questions/1007340/javascript-function-aliasing-doesnt-seem-to-work) – HoLyVieR

+0

確切的重複[「未捕獲的TypeError:Chrome中的非法調用」](http://stackoverflow.com/questions/9677985/uncaught-typeerror-illegal-invocation-in-chrome) –

回答

86

這是因爲你失去了函數的「上下文」。

當你撥打:

document.querySelectorAll() 

功能的情況下是document,並且將訪問作爲this通過該方法的實施。

當您只需撥打q就不再有上下文 - 而是「全局」對象window

querySelectorAll的實施嘗試使用this,但它不再是DOM元素,而是Window對象。該實現嘗試調用某個Window對象上不存在的DOM元素的某種方法,解釋器毫不意外地稱其爲犯規。

要解決這個問題,在Javascript中的較新版本使用.bind

var q = document.querySelectorAll.bind(document); 

,這將確保所有q後續調用具有正確的上下文。如果你還沒有得到.bind,使用此:

function q() { 
    return document.querySelectorAll.apply(document, arguments); 
} 
+2

哦,很好的通話。你是對的,因爲我可以這樣做:q.apply(document,['body']);它的工作原理。 – user1152187

+0

請注意,這並不需要在IE中爲內置函數工作。例如,console.log在那裏沒有應用程序方法。 – hugomg

+0

@missingno它在Chrome上很好 - 另一個IE「特別」我猜 - 嘆... – Alnitak

-1

在我的情況下非法調用發生因未申報傳遞變量作爲自變量。 確保在傳遞函數之前聲明變量。

0

它可能會發生很多原因,最常見的原因之一是,你正在調用一些既是變量又是函數的東西。

<body> 
<input type="button" value="-" onclick="changeTime(this)"> 
<script> 
    var changeTime = document.getElementsByClassName("changeTimes"); 
    function changeTime(t){ 
      console.dir(t); 
     } 
</script> 
</body> 

所以在這種情況下,目前尚不清楚其中「changeTime」我們呼籲,變量或函數,因此「非法調用」。

相關問題