34

次の表示が最後に向かって「持ち上げられた」理由を完全には理解していません。

var x = 'set';
var y = function () 
{
    // WHAT YOU DON'T SEE -> var x; 
    // is effectively "hoisted" to this line!

    if (!x) 
    { 
        // You might expect the variable to be populated at this point...it is not
        // though, so this block executes
        var x = 'hoisted'; 
    }

    alert(x); 
}

//... and this call causes an alert to display "hoisted"
y();

任意のポインタをいただければ幸いです。

4

7 に答える 7

35

巻き上げに関する MDN Docs のvar引用、

変数の宣言 (および一般的な宣言) は、コードが実行される前に処理されるため、コード内の任意の場所で変数を宣言することは、変数を先頭で宣言することと同じです。これは、変数が宣言される前に使用されているように見えることも意味します。この動作は、変数宣言が関数またはグローバル コードの先頭に移動されているように見えるため、「巻き上げ」と呼ばれます。

したがって、あなたの場合、JavaScript は、ローカル変数 (外部で宣言 xされたものではない) が関数のどこかで定義されていることを認識していますが、実行が代入ステートメントに到達するまで、その実際の値を認識しませんx(宣言はコンパイル時に処理され、代入は実行時に行われます)代入が完了するまで、デフォルト値undefinedが使用されます。undefinedは falsyであるため、条件

if (!x) {

が満たされ、割り当てステートメントが実行されます。そのためhoisted、アラート ボックスが表示されます。


x関数内で宣言していないとしましょう。

var x;

var y = function () {
    if (!x) {
        x = 'hoisted';
    }
    alert(x);
}

y();
alert(x);

ここでは、は関数内のどこにも宣言されていないため、実行時に JavaScript は上位のスコープxを探します。xこの場合、関数のすぐ外側にあることがわかります。それで、それxが使用されます。に割り当てhoistedたのでx、インナーalertも言いhoisted、機能を離れた後、alert(x)アラートもしhoistedます。

于 2015-04-16T06:52:46.650 に答える
12

変数宣言は、スコープの先頭に引き上げます。したがって、あなたのコードはこれと同等です:

var x = 'set';
var y = function () {
    var x;
    if (!x) {
        x = 'hoisted';
    }
    alert(x);
}

y();

y実行されると、var x外側のスコープがシャドウされるため、関数xの内側は宣言の最初の行の後にあります。yxundefined

于 2015-04-16T06:51:59.057 に答える
2

この回答は、変数のさまざまなスコープを非常に詳細に説明しています。特定のケースでは、次への参照を使用できます。

this.x; 

関数外でグローバル x 変数にアクセスする。関数内で未定義の変数にアクセスしようとしているため、thisキーワードを使用して関数外の変数を参照します。

そして、の部分

if(!x)

あなたがテストしているので、それは本当です:is falseそしてxその点ではundefined、関数スコープに存在しないためでありundefined、JS の false 値の 1 つと見なされます。詳細については、こちらをご覧ください

于 2015-04-16T06:58:44.687 に答える