2012-03-01 27 views
8

は、私がメッセージを警告する簡単な機能を持っていると言います。私は内側にそれを置くときこのクロージャはなぜ機能しますか?私はそうのようにそれを呼び出すとき</p> <pre><code>function callMessage(msg){ alert(msg); } </code></pre> <p>さて、それは動作しません:

function sayHi(){ 
     var hey = "hi there" 
     setTimeout(function(){callMessage(hey);}, 1000); 
    } 
    sayHi(); 

はなぜしか見え「ねえ」変数です:エラー

function sayHi(){ 
     var hey = "hi there" 
     setTimeout("callMessage(hey)", 1000); 
    } 
    sayHi(); 

「ねえが定義されていない」しかし、私は匿名関数の内部でそれを呼び出したとき、それは作業を行い例外匿名機能?

+1

評価されたときに取得することができない私はまただろうこれを試して; 'setTimeout(" var hey = 'hi there'; callMessage(hey) "、1000);' – mindandmedia

+0

私があなただったら、私は次のようなものを読んでいたでしょう:http://www.digital-web.com/articles/scope_in_javascript/ –

答えて

14

の後にコードが評価され、現在の有効範囲が残っています。その時点でheyは未定義です。

2番目の例 - setTimeoutを使用する適切な方法 - は、setTimeout()を呼び出すときに作成された匿名関数を使用します。この無名関数は、現在のスコープのコピーも受け取ります。

+0

2番目の例では、クロージャーのボディーはそれまでに評価されません。 – sepp2k

+2

後で実行されるまで*実行されません。最初のものは*文字通り*評価されます( 'eval()')。スコープが使用されるヒントはなく、 "単なる文字列"であるためです。 –

+0

それは理にかなっています。私は匿名関数がその親スコープのコピーを持っているのを知らなかった – levi

6

「callMessage(hey)」は文字列であり、クロージャではありません。タイムアウトが実行されたときに評価され、この時点で変数heyは有効範囲にありません。

3

これは正常です。

2番目の例では、フィクスチャと呼ばれるものを作成します。これは実行コンテキストです。可変変数は、メモリ内の無名関数によって使用されるように保存されます。

はあなたの最初の例では、ちょっと変数は(ジャバスクリプトを使用して、後の変数を使用することを知ることができないので)フィクスチャ内に保存されていないので、文字列が

関連する問題

 関連する問題