8

私がこれを行う場合:

var a = 0;

(function () {
    var a = a; //want to make local a = global a
    ++a;
    console.log("fn",a);
})();

console.log(a);​

出力は次のとおりです。

fn NaN
0

なぜa自己実行関数の内部がなるのNaNですか?

私がそうすればそれがうまくいくことを私は知っています:

(function () {
    var b = a;
    ++b;
    console.log("fn",b); // fn 1
})();

しかし、私が最初のバージョンの道を行くと、それはNaN問題を抱えています。

なぜこうなった?

4

4 に答える 4

12

var a = a;実際var a; a = a;には可変巻き上げが原因です。これは、割り当ての時点で、古いaものが新しいもの(つまりundefined)によってすでにシャドウされていることを意味します。

このような問題を回避する最も簡単な方法は、値をパラメーターとして渡すことです。

(function (a) {
    ++a;
    console.log("fn",a);
})(a);

がグローバル変数の場合は、 wozが提案するようaに使用することもできますが、グローバル変数を使用することは通常は悪い考えであるため、パラメーターを使用することをお勧めします。var a = window.a;

于 2012-07-12T17:35:24.837 に答える
6

a関数式内の変数は、外部スコープで宣言された変数をシャドウします。a

NaN割り当てでは、次のようになります。

var a = a;

右側aは、実際aにはローカルスコープで参照しています。

変数の宣言は、関数が実際に実行を開始する前に行われます。これは一般に「巻き上げ」として知られています。

これは同じ変数であるため、undefined値を保持し、この値に任意の数値を追加しようとすると、次のようになりNaNます。

console.log(undefined + 0);
于 2012-07-12T17:36:27.253 に答える
2

JavaScriptでは、コードの実行を開始する前に、現在の実行コンテキスト(変数スコープなどを含む)が確立されます。

これが意味することは、ローカル変数名が最初に割り当てられるということです。巻き上げにより、関数内の任意の場所にあるvarステートメントのラベルは、現在の実行コンテキストでは未定義に初期化されます。(関数ステートメントもこのステップで初期化されます。)

次に、コードが実際に実行を開始します。aラベルは現在の実行コンテキストですでに予約されているため、var a = a;ローカルa未定義)をそれ自体に割り当てるだけです。

var a = window.aグローバルスコープに直接アクセスすることでスコープの問題を回避できるため、機能します。windowただし、 ;がないため、これはブラウザ以外の環境(Nodeなど)では機能しません。Nodeのグローバルオブジェクトはですglobal

于 2012-07-12T17:38:06.647 に答える
0

javascriptには変数の巻き上げがあるため、実行中のコードは次のようになります。

(function () {
    var a;
    a = a; //want to make local a = global a
    ++a;
    console.log("fn",a);
})();

したがって、最初にローカル変数aを未定義として使用し、次に未定義を変数aに割り当てます。

于 2012-07-12T17:35:43.427 に答える