2012-12-12 203 views
5

以下代碼在書Head First jQuery中提供。變量未定義,有時

function lightning_one(t) { 
$("#lightning1").fadeIn(250).fadeOut(250); 
setTimeout("lightning_one()", t); 
}; // end lightning_one 

它被這條線調用。

lightning_one(3000); 

所觀察到的行爲是閃電淡入和出一次,等待3秒,淡入和淡出一遍,然後繼續到淡入​​和淡出。 Firebug顯示沒有JavaScript錯誤。

我明白爲什麼我看到我所看到的。我想我會嘗試保持3秒的間隔,所以我改變了這一點:

setTimeout("lightning_one()", t); // nothing in the brackets 

這樣:

setTimeout("lightning_one(t)", t); // t is in the brackets 

當我刷新頁面,閃電淡入和淡出一次。 Firebug告訴我變量t是未定義的。

我的問題是,如果在我改變之後變量t沒有被定義,那麼在我改變它之前,命令是如何運行沒有錯誤的?它仍然有一個名爲t的變量。

更多信息

謝謝大家誰寫的意見和解答。根據記錄,在「結束」文件夾,代碼變成這樣:

lightning_one(); 

    function lightning_one(){ 
$("#container #lightning1").fadeIn(250).fadeOut(250); 
setTimeout("lightning_one()",4000); 
    }; 

我還沒說完適用章又是那麼我不知道如果代碼變化被建議以後。如前所述,這可能不是那裏最好的書。然而,這是我買的,我從中學習jQuery的基礎知識。

+4

他們真的把一個字符串傳給'setTimeout'?把那本書扔得很遠。 – Bergi

+0

我在想同樣的事情:我認爲用這種方式調用函數是一種不好的習慣......不是應該在書中教授的東西! – jahroy

+0

當我試圖自己找到答案時,我看到了很多單詞。調用不帶引號的函數是我不成功的一個努力。儘管如此,我仍然認爲準確的報價是最好的選擇。 –

回答

6

因爲setTimeout作爲字符串的第一個參數是eval -ed,這意味着它將查看未定義其中t的函數的外部範圍。第一個沒有問題,因爲你沒有在調用中使用任何變量,但第二個不是因爲t沒有在函數範圍之外定義。它實際上是本地的。

建議:根本不要使用eval。實際上,你不需要字符串參數。使用函數表達式:

setTimeout(function() { 

    lightning_one(t); 

}, t); 
2

工作:

setTimeout(function() { lightning_one(t); }, t); 

我敢肯定,從一個字符串調用的函數(並使其得到評估)是一種不好的做法,應該是避免。

+0

這個答案確實有效。 –