2011-01-10 89 views
0
function First() { 
setTimeout("Second()", 50) 
}; 

function Second() { //I'm very confident this conditional works fine 
if (document.getElementsByClassName("l")[0].href == 
     document.getElementById("myFrame").getAttribute("src")) 
    { 
    First();          
    } 
else 
    { 
    var newLink = document.getElementsByClassName("l")[0].href;  // 
    document.getElementById("myFrame").setAttribute("src", newLink); 
    }}; 

First(); 

問題是當First()被定義時,我得到第二個未定義的錯誤。這怎麼解決?簡單的javascript函數定義問題

+2

請發表您的實際代碼。這在大多數情況下不會發生。 – SLaks 2011-01-10 23:47:55

+0

是的,它似乎工作正常:http://jsfiddle.net/ctrlfrk/Usvty/(只要你有退出條件) – david 2011-01-11 00:00:32

回答

4

更新

你更新後的代碼是從原始的代碼完全不同。問題似乎是你傳遞給setTimeout的字符串(這讓我很驚訝,但很容易複製)。我會改變

function First() { 
    setTimeout("Second()", 50) 
}; 

function First() { 
    setTimeout(Second, 50); 
} 

...或者,如果你需要傳遞參數給Second

function First() { 
    setTimeout(function() { 
     Second(param0, param1); 
    }, 50); 
} 

(請注意,有沒有必要爲一個;末的一個函數聲明,但是一個在setTimeout之後不會出問題[你實際上不需要需要它,恐怖的即「分號插入」將在此插入它,但是...]。)

上面的第二個和第三個版本使用函數引用。您的原始使用的字符串,然後編譯,這是不必要的,似乎是問題(如this example using the string fails,但this one with the function reference works)。

原來的答案

如下的答案,你的問題中所引用的代碼是:

function First() {Second();}; 
function Second() {First();}; 

該代碼會工作得很好。這是一個無限循環(嗯,不是無限,因爲最終實現將不會有任何更多的堆棧空間返回地址),但直到它爆炸,因爲它會正常工作。 Example

如果您實際代碼看起來更像這樣它會失敗:

var First = function() { 
    Second(); 
}; 
First(); 
var Second = function() { 
    First(); 
}; 

...因爲這是很大的不同,它使用函數表達式(被處理爲步幅的一部分),而不是功能聲明(在進入範圍時進行處理,在任何分步代碼之前進行處理),並在定義Second之前調用First。有關函數表達式和函數聲明之間區別的更多細節,請參見this other answer here on StackOverflow

+0

不是我在做什麼 – 2011-01-11 00:11:16

0

我剛剛試過你的代碼並調用「Second();」第一。它在Chrome中運行良好。 當然會永遠循環。

在Javascript中,變量在調用函數時會很晚。全局對象也只是另一個變量,它也很晚才「綁定」。一切都可以在任何時候(異步)改變,這就是爲什麼一個函數不能要求另一個函數可用。 「失蹤」函數可能只是在函數調用之前由其他機制添加。只是在執行一個函數之前,JS運行時應該檢查這個函數是否在範圍中可用。

這就是爲什麼它可以在Chrome中使用。在Javascript中你實際上是在做這樣的事情:

var GLOB = this; // bind global obj to variable 

GLOB["First"] = function() { 
    GLOB["Second"](); 
}; 

GLOB["Second"] = function() { 
    GLOB["First"](); 
}; 

調用GLOB["Second"]();作品就像在Chrome中的魅力(和它循環當然)。也許你的瀏覽器/ JS-implementation/dev-tool對函數定義的限制更多,讓我們在定義之前不要使用函數。

然後你可以使用這個obj["funcname"] = function() {}的語法,它和function funcname(){}一樣,但是可能不會被你的「破解的」JS解釋器檢測爲錯誤。

我希望這有助於 尤文

1

好吧,我想我看到你的問題。我敢打賭你的代碼包含在一個函數內部,對吧?那麼就不會有這樣的東西了。

這是行不通的:

(function() { 
    function First() { 
     setTimeout("Second()", 50) 
    } 
    function Second() { 
     alert('hi!'); 
    } 
    First(); 
})(); 

但是這將工作:

(function() { 
    function First() { 
     setTimeout(Second, 50) 
    } 
    function Second() { 
     alert('hi!'); 
    } 
    First(); 
})();