2012-04-14 93 views
1

範圍問題,我認爲函數語句總是被提升到當前上下文的頂部。那麼爲什麼'hideNav()'在下面沒有定義?帶setTimeout的Javascript中的範圍問題

var t; 


function showNav(bflag){ 
clearTimeout(t); 
if(bflag===true){ 
    $("#tS2").stop(false,false).animate({ 
       'bottom':'0' 
      }, 1000); 
}else{ 

    t=setTimeout("hideNav()",1000); 

} 
} 

function hideNav(){ 
$("#tS2").stop(true,false).animate({ 
       'bottom':'-125px' 
      }, 1000); 
} 

回答

6

變化,

setTimeout("hideNav()",1000); 

setTimeout(hideNav, 1000); 

hideNav只在當前背景下定義,但你傳遞一個字符串setTimeout。當全局對象的上下文中發生超時時,該字符串將被評估。由於您的hideNav函數未在全局對象中定義,因此它將引發異常。

通過直接將函數的引用傳遞給setTimeout,您不必擔心它。

2

在這種情況下,請勿使用setTimeout()的字符串。

將其更改爲:

t = setTimeout(hideNav, 1000); 

使用字符串setTimeout()迫使它使用eval()來評估您的字符串,當它這樣做,它採用了全球範圍內,沒有你的地方背景。所以,我的猜測是hideNav()實際上並不是一個全局函數(你可能已經把這個代碼包裝在其他函數中)。

此外,最好使用直接函數引用而不是字符串,而且速度更快。記住當你使用直接函數引用時,不要在後面加括號。你想要一個函數的參考,你不想立即執行它,並傳遞返回值,這是它會做什麼,如果你使用t = setTimeout(hideNav(), 1000);