JavaScriptの「巻き上げ」に遭遇しましたが、このコードスニペットが実際にどのように機能するかわかりませんでした。
_var a = 1;
function b() {
a = 10;
return;
function a() {}
}
b();
alert(a);
_
(function a() {}
)のような関数宣言は、関数b
スコープの最上部に引き上げられますが、a
の値をオーバーライドしないでください(関数のため)宣言は変数の宣言をオーバーライドしますが、変数の初期化はオーバーライドしません)。したがって、アラートの値は1ではなく10になると予想しました!!
a
は_1
_に設定されますb()
が呼び出されますfunction a() {}
はホイストされ、グローバルa
をマスクするlocal変数a
を作成しますa
は_10
_に設定されます(関数a
を上書きします)a
(まだ_1
_)がアラートされますこれは、この例のコンパイル/解釈の順序がやや誤解を招くためです。 function a () {}
行は、関数の残りのいずれかが実行される前に解釈されるため、関数の最初の部分では、a
の値はfunction a () {}
になります。それを_10
_に再割り当てすると、関数b()
のローカルスコープでa
の値を再割り当てします。グローバルスコープの_a = 1
_。
これを確認するには、alert()
sなどを適切な場所に配置して、さまざまなポイントでa
の値を確認します。
(1)JavaScriptにはブロックステートメントスコープがありません。むしろ、ブロックが存在するコードに対してローカルになります。
(2)Javascriptの関数スコープ内の変数の宣言。つまり、関数で宣言された変数は、値が割り当てられる前であっても、その関数内のどこでも使用可能。
(3)関数の本体内では、ローカル変数は同じ名前のグローバル変数よりも優先されます。 グローバル変数と同じ名前のローカル変数または関数パラメーターを宣言する場合、実質的にグローバル変数を非表示にする。
コードは次と同じです:(read comment)
<script>
var a = 1; //global a = 1
function b() {
a = 10;
var a = 20; //local a = 20
}
b();
alert(a); //global a = 1
</script>
参照:
(1) JavaScript変数スコープ:
(2) Javascriptの巻き上げの危険な例
(3) 変数スコープ
あなたのコードで:
var a = 1; //global a = 1
function b() {
a = 10;
return;
function a() {} //local
}
b();
alert(a); //global a = 1
function a(){}
が最初に巻き上げられるため、ローカルスコープにa
が作成されます。a=10
を設定すると、グローバル変数ではなくローカル変数a
が設定されます。したがって、グローバル変数の値は同じままで、警告が表示されます1
JavaScript Scoping and Hoisting と同じ記事を読んだとき、著者は2つの冒頭のサンプルコードがコンパイラーで解釈されるものを見せたことがないので、私も混乱しました。
ここにあなたが提供した例と、ページの2番目があります:
var a = 1;
function b() {
function a() {} // declares 'a' as a function, which is always local
a = 10;
return;
}
b();
alert(a);
ページの最初の例は次のとおりです。
var foo = 1;
function bar() {
var foo; // a new local 'foo' variable
if (!foo) {
foo = 10;
}
alert(foo);
}
bar();
お役に立てれば