2012-07-27 132 views
5

我知道evalsetTimeout既可以接受一個字符串作爲(1日)參數,而且我知道,我最好不要用這個。我只是好奇,爲什麼是有區別:執行字符串代碼

!function() { 
    var foo = 123; 
    eval("alert(foo)"); 
}(); 

!function() { 
    var foo = 123; 
    setTimeout("alert(foo)", 0); 
}(); 

第一會的工作,第二個會給出錯誤:foo is not defined

他們是如何在幕後執行?

+1

不富走出去的範圍setTimeout的回調之前被調用? – 2012-07-27 08:57:55

+1

爲什麼與邪惡的東西搞亂^^不要使用其中任一:) – Andreas 2012-07-27 09:03:06

+0

一個有趣的相關觀點[這裏](https://stackoverflow.com/q/3492015/465053)。 – RBT 2017-10-07 09:21:44

回答

4

reference of setTimeout on MDN

String literals are evaluated in the global context, so local symbols in the context where setTimeout() was called will not be available when the string is evaluated as code.

相反,傳遞給eval()字符串文字在調用EVAL的上下文中執行。

+0

並且傳遞給'eval'的代碼將在'eval'執行的上下文中執行? – wong2 2012-07-27 09:03:29

+0

準確地說,字符串字面值是「就地」評估的並且可以訪問在該上下文中定義的變量。 – Wolfram 2012-07-27 09:05:02

+0

@ wong2其實它取決於你如何調用'eval'。在現代瀏覽器中,以下eval在全局範圍內:http://jsfiddle.net/4p9QY/,因爲它是間接評估。這裏有更多間接評估的例子http://perfectionkills.com/global-eval-what-are-the-options/#indirect_eval_call_examples – Esailija 2012-07-27 09:40:42

2

的setTimeout的eval在全球範圍內追加執行的,所以它不知道foo

這裏的reference對其進行備份:

String literals are evaluated in the global context, so local symbols in the context where setTimeout() was called will not be available when the string is evaluated as code.

0
!function() { 
    var foo = 123; 
    eval("alert(foo)"); 
}(); 

執行此代碼時,JavaScript會假裝第3行顯示「alert(foo)」。 Foo在函數的範圍內定義。

!function() { 
    var foo = 123; 
    setTimeout("alert(foo)", 0); 
}(); 

執行此代碼時,javascript會輸入一個新函數;即function() {alert(foo)}。在「新」功能的範圍內,foo未定義。

1

的setTimeout需要比函數參照和超時多個參數。超時輸入的任何內容都將作爲參數傳遞給您的函數。

setTimeout(myFunction(param1, param2), 0, param1, param2); 
0

爲補充的正確答案,這裏是eval一個電話,會給你同樣的行爲和錯誤在此情況下:

!function() { 
    var foo = 123; 
    window.eval("alert(foo)"); // <- note the window.eval, this is important and changes the behavior of the `eval` function 
}(); 

!function() { 
    var foo = 123; 
    setTimeout("alert(foo)", 0); 
}(); 

這個博客後接着在深度上不同類型的evalhttp://perfectionkills.com/global-eval-what-are-the-options/