1. 無視されやすいローカル変数
var a = 5;
(function(){
alert(a);
var a = a ;
alert(a);
})()
alert (a);
このコードの実行結果について考えてください。
実行後、それがあなたの想像と一致しているかどうかを確認しますか?
わかりました。このコードの中核となる知識ポイントは var a = a です。ここで、2 つの変数 a は匿名関数内のローカル変数であり、それらは同じであり、グローバル変数 a とは異なります。
なぜですか? ECMA 仕様の変数宣言ステートメントの定義を見てみましょう:
説明
変数ステートメントが FunctionDeclaration 内にある場合、
変数はその関数内の関数ローカル スコープで定義されます。それ以外の場合は、
となります。グローバル スコープ
で定義されます (つまり、10.1.3 で説明されているように、グローバル オブジェクトのメンバーとして作成されます) { DontDelete } を使用して、変数は実行スコープに入ったときに
作成されます。ブロックは新しい
実行スコープを定義しません。新しい
スコープを生成する変数は、作成時に
の AssignmentExpression の値が割り当てられます。
VariableStatement は、変数の作成時ではなく実行されます。
宣言では、スコープ環境に入った後、変数が作成され、初期値として未定義が与えられます。代入式の値は、変数の作成時ではなく、変数宣言ステートメントの実行時に変数に代入されます。
したがって、上記のコードは次と同等になります:
var a;
a = 5;
(function(){
var a;
alert(a);
a = a ;
alert(a) ;
})()
alert(a);
これは理解しやすいはずです。
2. 見落とされやすいグローバル変数
(function(){
var a = b = 5;
})()
alert(b);
これはゆうおじさんの日々 以前に共有したナレッジポイントは非常に有意義なので、ここでも分析してみます。
まず、実行結果が次のようになった理由を考えてみましょう。 5.
わかりました。その理由は var a = b = 5 という文にあります。
このステートメントを詳しく分析するために、引き続き ECMA 仕様の宣言ステートメントの定義を参照します。
var a = b = 5; は var a = b = 5; と同等です。 2 つのステートメント、後者は代入式であり、ECMA での定義は次のとおりです。
単純な割り当て ( = )
本番の AssignmentExpression : LeftHandSideExpression =
AssignmentExpression は次のように評価されます。
1. LeftHandSideExpression を評価します。 >3. GetValue(Result(2)) を呼び出します。
5. Result(3) を呼び出します。 > a = b = 5 の場合; まず、識別子式である左の式 a を実行します。仕様のセクション 10.1.4 によれば、その実行方法は次のとおりです:
コードをコピーします
コードは次のとおりです:
オブジェクトが Result(1) であり、プロパティ名が
である Reference 型の値を返します。ステップ 1.
5. 基本オブジェクトが null で、
プロパティ名が
である Reference 型の値を返します。
スコープ チェーンを検索して、a に最も近い参照を見つけます。明らかに、それは匿名関数内のスコープで見つかるため、変数 a が決定されます。
次に、右側の式 b = 5 を実行します。これはまだ代入式です。変数 b は匿名関数環境で宣言されていないため、ウィンドウ グローバルに移動します。 window.b を見つけるための環境は、グローバル変数として暗黙的に宣言され、最終的に値 5 が割り当てられます。ルールの 5 番目のステップに従って、式の結果も a に割り当てられます。最後に、a と b は両方とも 5 です。違いは、a がローカル変数であり、b がグローバル変数であることです。
(function(){var a = b = 5})() 式の全体的な実行シーケンスを見てみましょう。
1. 匿名関数に変数 a を作成します。
2.初期値は未定義です。
3. 変数 a への参照を取得します。
5. 変数 b への参照を取得します。 6. 5 の参照を b: window.b に割り当てます。
7. b = 5 の結果 5 を返します。 a:
の結果 5 を返します。この手順を理解すると、コードの最適化ポイントを見つけるのは難しくありません。変数 b をローカル変数として明示的に宣言するだけです。
var a,b;
a = b =
})( )