2012-01-08 95 views
17

我需要每10秒運行一次javascript函數。Javascript setInterval不工作

我理解的語法必須全力以赴的後續,但我沒有得到任何的成功:

function funcName() { 
    alert("test"); 
} 

var func = funcName(); 
var run = setInterval("func",10000) 

但是,這是行不通的。任何幫助?

+0

在這些情況下查看瀏覽器的錯誤控制檯所說的話總是一個好主意。 – Bojangles 2012-01-08 18:03:17

+0

你知道當你將'func''傳遞給'setInterval'和'func'具有什麼值時會發生什麼?閱讀[某些文檔](https://developer.mozilla.org/en/window.setInterval)總是有幫助的。 – 2012-01-08 18:10:19

+0

將一個字符串傳遞給'setInterval()'(這通常是一個糟糕的主意)導致它做一個'eval(「func」)''。這基本上就像這樣的一行JavaScript:'func;'什麼都不做。作爲一個字符串,你必須實際執行像'setInterval(「func()」,10000)'這樣的函數,但是傳遞實際的函數名稱比如'setInterval(funcName,10000)'好得多,並且永遠不要強制它首先使用'eval()'。 – jfriend00 2012-01-08 18:13:27

回答

95

許多其他的答案都關注一種可行的模式,但他們的解釋並不是真的很全面,因爲你當前的代碼不起作用。

您的代碼,以供參考:

function funcName() { 
    alert("test"); 
} 

var func = funcName(); 
var run = setInterval("func",10000) 

讓我們打破這種成塊。你的功能funcName沒問題。請注意,當您致電funcName(換句話說,您運行它)時,您將提醒"test"。但請注意,funcName() - 圓括號表示「調用」或「運行」函數 - 實際上並不返回值。當一個函數沒有返回值時,它的默認值爲undefined

當你調用一個函數時,你需要在圓括號里加上它的參數列表。如果您沒有任何參數來傳遞函數,則只需添加空括號,如funcName()。但是當你想引用函數本身,而不是調用它時,你不需要括號,因爲括號表示要運行它。

所以,當你說:

var func = funcName(); 

你實際上聲明一個變量func具有的funcName()值。但請注意括號。 funcName()實際上是funcName的返回值。正如我上面所說,因爲funcName實際上沒有返回任何值,所以它默認爲undefined。換句話說,您的變量func實際上將具有值undefined

然後你有這樣一行:

var run = setInterval("func",10000) 

功能setInterval有兩個參數。第一種是經常運行的函數,第二種是每次運行函數之間的毫秒數。

但是,第一個參數確實應該是一個函數,而不是一個字符串。如果它是一個字符串,那麼JavaScript引擎將在該字符串上使用eval。因此,換句話說,你的setInterval運行下面的JavaScript代碼:

func 
// 10 seconds later.... 
func 
// and so on 

然而,func只是一個變量(使用值undefined,但這是那種無關)。因此,每隔十秒鐘,JS引擎就會計算變量func並返回undefined。但這並沒有真正做到。我的意思是,它在技術上每10秒就會被評估一次,但是你不會看到任何影響。

解決方法是給setInterval函數運行而不是字符串。所以,在這種情況下:

var run = setInterval(funcName, 10000); 

注意,我沒有給它func。這是因爲func而不是在你的代碼中的一個函數;這是值undefined,因爲您將它分配給funcName()。就像我上面所說的那樣,funcName()會調用函數funcName並返回函數的返回值。由於funcName不返回任何內容,因此默認爲undefined。我知道我現在已經多次說過了,但這確實是一個非常重要的概念:當你看到funcName()時,你應該想到「funcName的回報值」。當你想引用一個函數本身,就像一個單獨的實體一樣,你應該捨棄括號,所以你不要把它稱爲:funcName

因此,對於您的代碼另一個解決辦法是:

var func = funcName; 
var run = setInterval(func, 10000); 

然而,這是一個有點多餘:爲什麼要用func代替funcName

或者您也可以通過修改兩位留儘可能忠實於原代碼:

var func = funcName; 
var run = setInterval("func()", 10000); 

在這種情況下,JS引擎將評估func()每十秒鐘。換句話說,它會每十秒鐘提醒"test"。然而,正如着名的話,eval is evil,所以你應該儘量避免它,只要有可能。

此代碼的另一個轉折是使用匿名函數。換句話說,一個沒有名字的函數 - 你只需將它放在代碼中,因爲你不在乎它叫什麼。

setInterval(function() { 
    alert("test"); 
}, 10000); 

在這種情況下,因爲我不在乎什麼函數被調用時,我剛剛離開一個通用的,無名(匿名)函數存在。

+4

謝謝你的明確答案! – mauzilla 2012-01-08 19:15:54

2

那是因爲你要傳遞一個函數,而不是一個字符串:

function funcName() { 
    alert("test"); 
} 

setInterval(funcName, 10000); 

您的代碼有兩個問題:

  • var func = funcName();立即呼叫功能,並指定返回值。
  • 即使您使用setInterval的不良和不贊成使用eval的語法,僅僅"func"無效。這將是setInterval("func()", 10000)來調用函數eval-like。
2

試試這個:

function funcName() { 
    alert("test"); 
} 

var run = setInterval(funcName, 10000) 
4

變化setInterval("func",10000)要麼setInterval(funcName, 10000)setInterval("funcName()",10000)。前者是推薦的方法。