次の JavaScript コードを実行するとアラートがどのような値を出力するかご存知ですか?
var foo = 1; bar() {
if (!foo) {
var foo = 10>}
alert(foo);
;
「10」という答えに驚いた場合は、さらに混乱するかもしれません:
[/code]
var a = 1;
function b() {
a = 10 ;
return;
function a() {}
}
alert(a);
[/code]
ブラウザは「1」を警告します。それで、何が起こったのでしょうか?これは少し奇妙で、少し危険で、少し混乱しているように見えるかもしれませんが、実際には、この言語の強力な表現機能です。この動作を定義する標準があるかどうかはわかりませんが、私はそれを説明するために「ホイスティング」を使用することを好みます。この記事ではこのメカニズムを説明しますが、その前に、JavaScript のスコープについて必要な理解をしておきましょう。
JavaScript のスコープ
スコープは、JavaScript の初心者にとって最もわかりにくい部分の 1 つです。実際、初心者だけでなく、スコープを完全に理解できない経験豊富な JavaScript プログラマーにもたくさん会いました。 JavaScript のスコープが非常に複雑である理由は、JavaScript が C 言語ファミリーのメンバーに非常によく似ているためです。次の C プログラムを見てください:
コードをコピーします
コードは次のとおりです: #include int main() { int x = 1; // 1
if (1); 🎜>int x = 2;
printf("%d, ", x); // 2
}
printf("%dn", x); // 1
}
このプログラムの出力は 1,2,1 です。これは、C シリーズ言語にはブロック レベルのスコープがあり、if ステートメントと同様に、新しい変数がこのブロック レベルのスコープで宣言されるためです。これらの変数は外側のスコープには影響しません。しかし、JavaScript の場合はそうではありません。 Firebug で次のコードを試してください:
コードをコピーします
コードは次のとおりです:
このコードでは、Firebug は 1、2、2 を表示します。これは、JavaScript には関数レベルのスコープがあるためです。これは C ベースの言語とはまったく異なります。 if ステートメントと同様、ブロックは新しいスコープを作成しません。新しいスコープを作成するのは関数のみです。
C、C#、C#、または Java に精通しているほとんどのプログラマにとって、これは予期せぬことであり、歓迎されないことです。幸いなことに、JavaScript 関数には柔軟性があるため、この問題には解決策があります。関数内に一時的なスコープを作成する必要がある場合は、次のように実行します:
コードをコピーします
コードは次のとおりです:
}
// x は 1 のままです。
}
この側面は確かに非常に柔軟で、次のように使用できます。ブロック内だけでなく、一時的なスコープの場所。ただし、時間をかけて JavaScript のスコープを理解することを強くお勧めします。これは本当に強力で、この言語の私のお気に入りの機能の 1 つです。スコーピングをよく理解するとホイスティングも理解しやすくなります。
宣言、名前、ホイスティング
JavaScript では、スコープ内に 4 つのタイプの名前があります。
1. 言語定義: すべての関数 フィールドには、デフォルトで this と引数が含まれます。
2. 仮パラメータ: 名前付きの関数パラメータは関数本体のスコープに入ります。
3. 関数の宣言: 関数 foo() {} の形式。
4. 変数宣言: var foo; の形式。
関数宣言と変数宣言は、JavaScript インタプリタによって常にそれらを含むスコープの先頭に暗黙的にホイストされます。明らかに、言語自体の定義と関数パラメーターはすでにスコープの最上位にあります。これは次のコードのようなものです:
コードをコピーします
コードは次のとおりです: