JavaScript 自体は単純な言語ですが、その変数スコープの問題で多くの人がめまいを感じます。これは主に JavaScript クロージャの存在が原因です。この記事は、JavaScript の変数スコープの問題を詳しく説明するつもりはありません (実際、私にはこのトピックについて詳しく話す能力がありません)。また、この記事では「クロージャ」のトピックについてのみ説明します。最も実用的な JavaScript スコープの知識ポイント。
1. JavaScript スコープの分類
JavaScript には、グローバル (ウィンドウ) と関数レベル (関数) の 2 つのスコープがあります。関数レベル(関数)を「ブロックレベル(中括弧{}レベル)」として理解してはなりません。
2. JavaScript のグローバル変数とローカル変数を区別して定義する
1.1 var キーワードの有無にかかわらず、すべての関数の外部で定義された変数はグローバル変数です。グローバル変数は実際には window オブジェクトの属性に解析されるため、「window.global 変数名」メソッドでアクセスできます。必要な場合を除き、変数名を使用して直接アクセスすることをお勧めします。次の例は、グローバル変数を定義する最も一般的な方法を示しています。
var msg1='これはメッセージ 1';
msg2='これはメッセージ 2';
alert(window.msg1); //これはメッセージ 1 にアクセスします。 🎜>alert(window .msg2); //これはメッセージ 2
alert(msg1); //これはメッセージ 1 ウィンドウ キーワードのアクセス方法を省略します
alert(msg2); //これはメッセージ 2
function otherFunction (){} //その他の関数またはオブジェクト宣言コード
var otherObject={};
1.2 グローバル変数は関数内で定義および取得することもできます (ローカル変数)可変ランタイム環境)。定義方法はvarキーワードを使用せず、グローバル変数名で参照するだけでローカル環境で簡単にグローバル変数の内容を取得できます。グローバル変数と同じ名前のローカル変数が関数内で定義されている場合、この時点で同じ名前のグローバル変数を使用する必要がある場合、関数本体は最初に独自のローカル変数を使用することに注意してください。ウィンドウ接頭辞を追加してください。例:
var msg1='これはmessage 1' ;
var msg3='これはメッセージ 3';
function otherFunction()
{
msg2='これは var キーワードを使用していない'; a global Variable
var msg3='Message 3';
alert(msg1); //これはメッセージ 1 (もちろん、関数の深さに関係なく、外部で定義されたグローバル変数にアクセスできます)ネストされている場合、正しく取得できます。このグローバル変数は JavaScript クロージャーの表現の 1 つです)
alert(msg3) //メッセージ 3 (ローカル変数 msg3)
alert(window.msg3);メッセージ 3 (ウィンドウ プレフィックスは同じ名前のグローバル変数 msg3 にアクセスします)
alert(this.msg3); //これはメッセージ 3 (otherFunction () がグローバル環境で定義されているため、この時点ではotherFunction () の this も window を指しているので、window.msg3 が this.msg3 と等しいことがわかります)
}
otherFunction();
//msg1 は otherFunction 関数の外で定義され、msg2 は定義されています内部はまだグローバル変数です
alert(window .msg1); //これはメッセージ 1
alert(window.msg2); //これはメッセージ 2
2.1 var の使用キーワード、関数本体で定義された変数はローカル変数であり、この変数はすべてのステートメント ブロック ({}) とその下のサブ関数で使用できます。この変数には、この関数内のどこからでもアクセスできますが、この関数の外で「直接」アクセスすることはできません (クロージャにより間接アクセスまたはプロキシ アクセスが許可されます。このナレッジ ポイントはこの記事の範囲外です)。例:
function showMsg()
{
if (true)
{
var msg='これはメッセージです';
}
alert(msg); //これはメッセージです
}
showMsg ();
alert(typeof(msg)); //undefiend
//if {} 中括弧内で定義された変数 msg は、if の外側の showMsg() 内でもアクセスできますが、showMsg() の外側ではアクセスできません。
2.2 親関数の変数には子関数からアクセスできますが、子関数の変数には親関数からアクセスできません。明らかに、これは関数レベルのスコープと一致しています。の冒頭で述べた。父親の方が明るく、息子はケチなようです。例:
コードをコピー コードは次のとおりです:
function showMsg()
{
var MsgA='メッセージ A';
this.setMsg=function(msg)
{
var MsgB='メッセージ B' ;
alert(MsgA); //メッセージ A (サブ関数 setMsg() は親関数 showMsg() のローカル変数 MsgA にアクセスできます)
}
alert(MsgB);が定義されていません (子関数で定義された変数 MsgB は親関数でアクセスできません)
}
var sm=new showMsg();
sm.setMsg('メッセージ文字列'); 🎜>
3. いくつかの注意点と使用スキル
1. 変数の混同や上書きを避けるために、ローカル変数の定義に var キーワードを追加することを忘れないでください。必要に応じて、使用後に変数を積極的に解放する必要があります)、つまり「変数名 = null」)、すべての変数を各関数本体の先頭で定義することをお勧めします。例:
var msg='Message' ;
function showMsg()
{
var msg; //ここで誤ってグローバル変数と同じ変数名を使用した場合でも、グローバル変数を同じ変数名で上書きすることを心配する必要はありません。名前
var a;
var c;
for (a=0;athis.setMsg=function(){}
}
2. 匿名関数を上手に使用して、名前の競合や変数の汚染を減らします。次の 2 つのコードは実際に同じ関数を実装していますが、最初のコードの書き方は、匿名関数などで使用したい変数名を大胆に使用でき、その必要はありません。自分が定義した変数が他の人の定義や他の場所にある自分の定義を上書きすることを心配しないでください。
//匿名関数を定義し、この匿名関数は、一般的な JS フレームワークの慣行である名前の競合や変数の汚染を効果的に軽減できます。
(function()
{
var msg='This is message';
alert( msg );
})();
document.write(msg); //msg は未定義です (匿名関数以外のメソッドは msg 変数を呼び出すことができません)
//------ ----------------------
var msg='これはメッセージです'
alert(msg); >3. インスタンス化を必要としない関数内のグローバル変数にアクセスするために、ウィンドウの代わりにこれを使用することはお勧めできません。通常、 this キーワードを使用する関数は JavaScript クラスとして扱われる必要があります (私はクラス名に「cls」というプレフィックスを付けるのが好きです)。以下の関数を通常の関数として呼び出すだけの場合、通常はグローバル変数を操作するため、 this キーワードは出現しないはずです。例:
コードをコピー
this.showMsg=function()
{
alert(this.msg);
}
}
sMsg=new clsMsg();
sMsg.msg='これは新しいメッセージです';
4. 関連する知識ポイントのガイドライン
以下の関連知識ポイントは、JavaScript 変数のスコープをより深く理解するのに役立ちます。この記事では、今のところ詳しく説明しません。後で別のスペースで説明します。
(1)
JavaScript の「事前解析」を理解する
(2)
JavaScript クロージャー