2017-09-01 5 views
0

「You Do not Know JS」シリーズの「Scope & Closures」という本を読んでいます。 は、このコードスニペットを通って行く:この場合レキシカルスコープの問題

function foo() { 
    var a = 2; 
    function bar() { 
     console.log(a); // 2 
    } 
    bar(); 
} 
foo(); 

、関数bar()のトップに掲揚されてはいけないと、このコードは、エラーを生成する必要がありますか?巻き上げた後、このコードは次のようにする必要がありますので、関数はトップと後で変数に掲揚されているため、これがある

function foo() { 
    function bar() { 
     console.log(a); 
    } 
    var a; 
    a = 2; 
} 

(少なくとも私が理解するもの)。そうでない場合は、私を修正してください。

+0

'console.log(a)'は 'bar()'が呼び出されるまで実行されません。その時まで 'a 'にアクセスしようとはしないので、' var a; 'は' bar() 'を呼び出そうとする前に処理されています。 –

答えて

2

彼らは両方とも上にまでを吊り上げているので、abarの範囲にあります。関数が "上"の変数ではないということです。関数の宣言と変数が同じ名前を持っている場合は、関数の宣言が優先されます。その理由は、変数がホイストされている場合、指定された名前の既存のバインディングがすでに存在する場合には作成されないからです。

「ホイスト」は便利な省略表現ですが、リテラルではありません。

  1. 実行コンテキストfoo
  2. への呼び出しオブジェクトに対して作成されます。fooは(問題の問題に集中するために、詳細の公平なビットを除外)呼び出されたときに何がが起こります(その例ではとaのような)識別子のバインディングを保持するためにコンテキストが作成されます
  3. すべての関数宣言が処理され、その識別子のバインディングがオブジェクトに追加されます同じ名前を持つション、最後の1勝)
  4. オブジェクトがすでにオブジェクトが、その後であることを

それらのバインディングを持っていない場合、すべての変数宣言が処理され、その識別子が対象に追加されます(例えば、バインディングに関連付けられた値は、aが参照されるときに使用され、aが設定されたときなどに設定されます)。

0

hoistingが実行され、コンパイル中にbarのコンパイルが呼び出されるまで機能しません。なぜbarにエラーが表示されるのですか? JavaScriptがどのようにコンパイルされ実行されているかの詳細をさらに知りたい場合は、ここで素敵なビデオです。https://www.youtube.com/watch?v=QyUFheng6J0

関連する問題