2012-07-27 5 views
5

を実行しますevalsetTimeoutはどちらも文字列を(1番目の)パラメータとして受け入れることができます。evalとsetTimeoutの差は文字列コード

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

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

最初はうまくいく、と第二がエラーを与える:foo is not defined

、彼らがシーンの後ろに実行されているどのように違いがある理由を私は興味が?

+1

setTimeoutコールバックが呼び出される前に、fooが有効範囲外になりますか? –

+1

邪悪なものを混乱させる理由^^これらのどちらも使用しないでください:) – Andreas

+0

興味深い関連するビューポイント[ここ](https://stackoverflow.com/q/3492015/465053)。 – RBT

答えて

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

+0

正確には、文字列リテラルは「インプレース」で評価され、そのコンテキストで定義された変数にアクセスできます。 – Wolfram

+0

@ wong2実際には 'eval'をどのように呼び出すかによって異なります。現代のブラウザでは、以下のevalはグローバルスコープにあります:間接的な評価であるため、http://jsfiddle.net/4p9QY/です。間接的な評価の呼び出しの例がここにあります。http://perfectionkills.com/global-eval-what-are-the-options/#indirect_eval_call_examples – Esailija

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/

関連する問題