この質問に対する真の答えは、「ホイスト」という用語によって抽象化されることが多いように感じます。これが実際に起こっていることです。
関数が JavaScript で実行されるたびに、その関数の新しい実行コンテキストが作成され、実行スタックにプッシュされます。したがって、2番目の例では、次のコードがあります。
var me = 1;
function findme(){
if(me){
var me = 100;
console.log(me);
}
console.log(me);
}
findme();
// undefined
このコードの実行の最初に (これが JavaScript 全体であると仮定して)、最初に起こることは、JavaScript エンジンがグローバルな実行コンテキストを作成することです。作成中に、そのコンテキスト内のすべての関数と変数にメモリを割り当てます。関数は想像どおりに割り当てられて初期化されますが、変数は最初に割り当てられるだけです (適切に初期化されません)。
したがって、この例でグローバル実行コンテキストを作成した後、関数 findme() は全体がメモリに割り当てられますが、変数 "me" は未定義の初期値で割り当てられます。グローバル実行コンテキストが作成された後、コードが実行されます。var me = 1; が見つかります。そして、「me」変数を undefined から 1 に更新します。実際には関数定義に対して何も行いませんが、「findme();」の関数呼び出しを見つけます。
この時点で、findme() 関数に入ります。そして実際、同じことが何度も繰り返されます。この関数の実行コンテキストが作成され、グローバル実行スタックにプッシュされ、これが実行中のコードになります。私の議論の最初の部分を理解していれば、「console.log(me);」に気付くと思います。「if」ステートメントの後の呼び出しは未定義です。なんで?これは、findme() 関数実行コンテキストが作成されたときに、最初に「me」変数を作成したためです。これは、「var me = 100;」によってコンテキスト内で認識されたためです。声明。ただし、「if」ステートメントは、グローバル実行スタックに関して専用の実行コンテキストを取得しません。したがって、「console.log(me);」if の外側では、 me 変数が実行され、関数の包括的なコンテキストで定義されています。
このすべてに従えば、JavaScript エンジンの仕組みの大部分を理解できたことになります。