學過JavaScript 腳本語言的都應該接觸過setInterval 函數.如何使用我想大家都知道,但是有時候對於剛剛接觸JavaScript的朋友來講,還是會在使用的時候碰到這樣或那樣的問題而感到困惑!以下是經常在QQ群中碰到問的最多的問題。如下圖:
首先聲明:本人JavaScript技術水平較低,以下所訴完全是依照自己的理解來做一些說明。如果有不當之處,還請批評斧正!以下就全當是在扯蛋吧,扯的很顯淺,
扯深了自己搞不定,還會扯疼的!
在JavaScript中的setInterval() 方法可按照指定的周期(以毫秒計)來調用函數或計算表達式。setInterval() 方法會不停地調用函數,直到 clearInterval() 被調用或窗口被關閉。由 setInterval() 返回的 ID 值可用作 clearInterval() 方法的參數來將其停止。
其實以上對函數的調用均能執行。首先我們看以下代碼:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title></title> <script type="text/javascript"> function fun() { alert(1); } setInterval("fun()",1000);//全局作用域下正常執行 setInterval(fun(),1000); //調用函數正常,setInterval調用出錯 setInterval(fun,1000); //正確 </script> </head> <body> </body> </html>
我所寫的代碼和提問題的人是相同的,唯一的區別就是函數名不同罷了!如果大家做了相關測試都應該知道,就以上代碼來說都會彈出結果1.
當然以上代碼其執行環境為全局。setInterval 第一個參數 可以是函數名、匿名函數、函數的引用以及其他可執行代碼。(個人理解)
setInterval("fun()",1000);
其中這種加引號的調用就可以理解為“可執行代碼” ,就行eval 一樣去執行。第一個參數,就是對fun方法的調用 。理所當然的彈出 1 。 一秒鍾間隔,一直執行。
setInterval(fun(),1000);
對於這種調用方式我不理解使用者用setInterval 的意圖為何.
fun() 是對函數的直接調用。也就是說當setInterval還沒有開始執行,函數fun就執行了。如果這個函數沒有返回值或者返回值不是可執行的函數或者其他的代碼的話,就以上代碼而言只是彈出1,之后就遍報錯了.
難道這樣的調用真的不可以嗎?其實是可以的!例如代碼:
function funone() { return function () { alert("qishiwoyenengzhixing"); } } setInterval(funone(), 1000); //每隔一秒鍾都會彈出 qishiwoyenengzhixing 你信不信,反正我信了
就我個人認為這種設計或者調用完全沒有任何意義。在此只做一下簡單的說明吧!
setInterval(fun,1000); //這種方法是正確的。
大家可以把這種調用setInterval的方式的第一個參數看作參數為 函數名或函數的引用。當然還可以直接使用匿名函數,如:
setInterval(function () { alert("我一秒中執行一次"); }, 1000);
有些人剛接觸JavaScript可能發現,在全局作用域下 setInterval("fun()",1000); 可以正常執行,但放到window.onload函數中卻不能執行。為什么呢?(其實一開始我也碰到了相同的問題)
代碼如下:
window.onload = function () { function fun() { alert(1); } setInterval("fun()",1000);//這個報錯了 未定義 重點在這一個 // setInterval(fun(), 1000); //這個和剛才全局的表現一樣 // setInterval(fun,1000);//這個沒有問題 };
setInterval("fun()",1000); 這種調用報未定義,在全局講解中我們已經說過了 。可以把帶引號的參數理解為 “可執行代碼” ,
而setInterval現在把以引號包括的“可執行代碼進行”處理。就像eval一樣給予執行。其在執行中 fun() 執行環境發生了變化,不是在window.onload方法下,而是在全局執行環境中也就是window.大家應該知道JavaScript存在作用域鏈,由內向外依次查找。內部可以訪問其上層的函數和變量,而外部卻不能訪問內部的函數和變量。JavaScript有一個預編譯處理,首先對函數和變量進行預編譯。也就是說其函數和變量作用域是在其聲明的時候確定的,而不是在執行的時候確定。當setInterval把"fun()"執行環境換為全局的后,對fun的調用是無效的。因為全局不能這樣訪問局部的函數和變量。window.onload相對於window來說就是局部的。其實就是一個作用域的問題。
對於setInterval(fun(), 1000)和setInterval(fun,1000)的調用其執行環境並沒有改變,所以是可以訪問的到的window.onload下聲明的函數。只不過setInterval(fun(), 1000)執行fun函數后 會報錯的,setInterval其調用錯誤。為什么錯誤?在之前已經講過了,這里就不啰嗦了!
為了證明自己的的理解為第一個參數加引號 以“可執行代碼” 執行。以下是自己寫的兩段代碼進行的測試:
function fun1() { alert(1); } setInterval("alert(fun1)",2000);//你認為結果是多少?
setInterval("var a=1;var b=2;c=a+b;alert(c);",1000); //這個呢?
以上內容是個人的理解,因為自己在之前也碰到了相同的問題!也許僅僅對於剛學JavaScript的朋友有一點幫助。當然可能存在錯誤(包括錯別字),歡迎各位大牛批評斧正!。如果你有意幫助本人提高,請留下你寶貴的建議。請不要因此進行謾罵(其實完全可以把此作為一個笑話)!謝謝!