いくつかの JS コードを記述している限り、単純な var で十分です。では、JS コンパイラーの背後では何が起こっているのでしょうか?コードを段階的に見ていきましょう。
x = 1; x);
var y = function() {
var x = 2;
y(); >
上記のコードは、1、未定義、正解の場合は 2 も出力します。私にとって、最初の反応は 1、1、2 です。 2 番目の出力が unknown になるのはなぜですか?上記でグローバル変数 x を明確に定義しましたが、なぜそれが見つからないのでしょうか?
その理由は、js コンパイラーがこの y 関数を実行するときに、本体内で宣言された変数を宣言の先頭に進めるためです。例: var x=2; コンパイラはまず本体の先頭で var x を宣言します。実際、上記のコードは次のコードと同等です:
コードをコピーします
コードは次のとおりです: x = 1; alert(x); var y = function() {
var x;//x にはこの時点では値が割り当てられていません。未定義。
alert(x);
x = 2;
y();
ただし、コード var x = 2; を削除すると、内部的に var 宣言がなくなります。常にスコープを検索します。このときの x はグローバル x です。
より興味深い例を見てみましょう。
コードをコピーします
コードは次のとおりです。
function b() {
a = 10; return;
function a() {}
} b();
例は非常に簡単です。最初の例は 10 を出力し、2 番目の例は 1 を出力します。これはなぜでしょうか?さらに、2番目の例を返しました。論理的には 10 が出力されるはずです。当時はJSコンパイラが裏でトラブルを起こしていたためでした。
2 つのコードの違いは、2 番目の例には追加の関数 a(){} があるため、この関数本体には何もなく、呼び出しも行われないことです。
実際、JS コンパイラは関数 a() {} を舞台裏で var a=function (){} にコンパイルします。この時点では、関数内には a=10 もありますが、JS スコープによれば、a の外側は 1 のままです。まず内部の a を探し、見つからない場合は 1 つ上のレベルに上がって探します。
最後のアラート (a) には 1 が表示されます。