7

Javascriptの巻き上げについて読んでいるときに、次のことを試しました。最初のものと2番目のものの出力が異なる理由はわかりません。前もって感謝します。(これが巻き上げに関係しているのかどうかさえわかりません。)

var me = 1;
function findme(){
   if(me){
    console.log( me );//output 1
    }
  console.log( me ); //output 1
}
findme();

ただし、次の出力は未定義です。

var me = 1;
function findme(){
 if(me){
    var me = 100;
    console.log(me); 
    }
  console.log(me); 
}
findme();
// undefined
4

4 に答える 4

8

変数宣言はすべての関数の先頭に持ち上げられますが、値の割り当てはそのままです。したがって、2 番目の例は次のように実行されます。

var me = 1;
function findme () {
    var me;  // (typeof me === 'undefined') evaluates to true
    if (me) { // evaluates to false, doesn't get executed
        me = 100;
        console.log(me); 
    }
    console.log(me); 
}
findme();
于 2013-01-13T01:19:22.707 に答える
3

2 番目の例のブロック内のローカル変数の宣言はif、関数全体に引き上げられます。

したがって、me関数内では、グローバル変数ではなく、常にローカル変数を参照します。

ただし、変数のは巻き上げられないため、常にundefinedあり、if決して入力されません。

于 2013-01-13T01:17:52.070 に答える
2

a を巻き上げvarても代入は巻き上げられず、宣言だけが巻き上げられます。したがって、次のように解析されます。

function findme(){
  var me;
  if(me){
    me = 100;
    console.log(me); 
  }
  console.log(me); 
}

ifステートメントが実行meされると、関数に対してローカルに宣言されますが、(undefined値がありません)。undefinedは偽なので、あなたの条件は真ではありません。

これが、常に関数の先頭でローカル変数を宣言するのが通例である理由です。好むと好まざるとにかかわらず、ローカル変数はそこに配置されるからです。

于 2013-01-13T01:22:31.153 に答える
0

この質問に対する真の答えは、「ホイスト」という用語によって抽象化されることが多いように感じます。これが実際に起こっていることです。

関数が 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 エンジンの仕組みの大部分を理解できたことになります。

于 2015-10-11T20:20:44.113 に答える