10

まず、コードを見てみましょう。

var a=0;
b=1;
document.write(a);
function run(){
    document.write(b);
    var b=1;
}
run();

結果は だと思いますが01、実は結果は0undefinedです。

次に、このコードを変更します。

var a=0;
b=1;
document.write(a);
function run(){
    document.write(this.b); //or document.write(window.b)
    var b=1;
}
run();

うん、今回は予想通り。01. 私は理解できません、なぜですか?

さらに興味深いことに、コードをもう一度変更します。

var a=0;
b=1;
document.write(a);
function run(){
    document.write(b);
    //var b=1;       //I comment this line
}
run();

結果は01。

それで、誰でもこれを説明できますか?

あなたの視点を共有していただきありがとうございます。このコードを単純化します

b=1;
function run(){
    console.log(b); //1
}

2:

b=1;
function run(){
    var b=2;
    console.log(b); //2
}

三:

b=1;
function run(){
    console.log(b); //undefined
    var b=2;
}
4

4 に答える 4

17

関数内で変数を参照する場合、JS はまずその変数が現在のスコープ、つまりその関数内で宣言されているかどうかをチェックします。見つからない場合は、含まれているスコープを探します。それでも見つからない場合は、次のスコープを検索し、最終的にグローバル スコープに到達するまで繰り返します。(関数を相互にネストできることに注意してください。これにより、いくつかのレベルの包含スコープを取得できますが、もちろん例ではそうしません。)

ステートメント:

b=1;

without は、最初の関数で local も宣言することを除いvarて、どの関数内でもアクセスできるグローバル変数を宣言します。これは可変シャドウイングと呼ばれます。b

「しかし」、「私はb document.write(b)にローカルを宣言します」と言います。ここで、宣言「巻き上げ」に遭遇しています。関数内の任意の場所で宣言された変数は、JS インタープリターによって、関数の先頭で宣言されているかのように扱われます (つまり、先頭に「巻き上げられる」)、値の代入はその場で行われます。したがって、最初の関数は実際には次のように実行されます。

function run(){
    var b;              // defaults to undefined
    document.write(b);  // write value of local b
    b=1;                // set value of local b
}

を使用する 2 番目の関数では、 が を参照し、グローバル変数は基本的に のプロパティでthis.bあることがわかります。したがって、グローバルにアクセスし、ローカルを無視しています。thiswindowwindowb

3 番目の関数では、ローカルをまったく宣言しないbため、グローバルなものを参照します。

于 2012-08-15T02:30:33.597 に答える
3

var ディレクティブは実行前の段階で処理され、 は の前にbローカル変数になるdocument.write(b);ので、その時点でbundefinedです。

注:変数への値の割り当ては実行時に行われるため、コードは次のようになります。

function run(){
    document.write(b);
    var b=1;
}

以下と同じです:

function run(){
    var b;
    document.write(b);
    b=1;
}

追記:

これが、関数の先頭にすべての var 定義を配置することをお勧めする理由です。

于 2012-08-15T02:16:40.773 に答える
3

を記述するb = 1と、グローバル オブジェクトにプロパティが作成されます。
通常の関数でbは、このグローバルを参照します。

関数には が含まれているため、関数var b;bではローカル変数を参照します。(varステートメントがどこにあるかに関係なく、関数全体でローカル変数を作成しますvar)。
ただし、varステートメントの実行可能部分 ( b = 1) は、その時点でのみ実行されます。

于 2012-08-15T02:10:58.090 に答える