ここにちょっとしたコードが...
var x = 5;
function fn() {
x = 10;
return;
function x() {}
}
fn();
alert(x);
これがjsFiddleです
やっぱりfunction x() {}
呼ばれるの?return
なぜ10に警告しませんか?
ここにちょっとしたコードが...
var x = 5;
function fn() {
x = 10;
return;
function x() {}
}
fn();
alert(x);
これがjsFiddleです
やっぱりfunction x() {}
呼ばれるの?return
なぜ10に警告しませんか?
function x() {}
はスコープの先頭に引き上げられ、これにより、評価される前にローカル変数が効果的に作成されます。fn
x
x = 10;
関数がに設定されていません10
。
更新:上記の文は間違っています。x
実際にはに設定されてい10
ます。var
は宣言に使用されませんが、使用された場合でも、以下の引用符の最後の文は、名前の宣言部分のみを参照し、への割り当てx
は参照しません。10
MDN(強調鉱山)から:
働き
スコープの動作が異なる3つのフォーム:
- 宣言:親関数のトップレベルのステートメントとして
- その関数に初期化されるvarバインディングのように動作します
- 初期化は、 varsの上にある親関数の最上部に「ホイスト」します
var
- 関数スコープ
- その機能のトップにホイスト
- 同じスコープ内の同じ名前の再宣言はノーオペレーションです
関数xが一番上に浮くので、関数を10に割り当てます
fn内で関数xを宣言しています。したがって、ローカルスコープバージョンのxを使用しています。関数xがどの時点で宣言されているかは関係ありません。xを10に設定したときに実際に行っているのは、xの関数を10に設定していることです。
このコードは5にも警告します:
var x = 5;
function fn() {
x = 10;
return;
var x;
}
fn();
alert(x);
重要な点は、ローカル変数 x
を宣言しているということです。returnステートメントの後に変数を宣言することも重要ではありません-それはまだローカル変数です。
宣言を削除すると、x
はローカル変数ではなくなったため、代わりに10が返されます。
これは、JavaScriptで変数の巻き上げが機能する方法が原因です。変数宣言は引き上げられますが、割り当ては引き上げられません。関数宣言も関数本体と一緒に持ち上げられます(関数式はそうではありませんが)。
したがって、コードはこれを効果的に実行しています。
var x = 5;
function fn() {
var x;
x = function () {}
x = 10;
return;
}
fn();
alert(x);
したがって、関数内はローカルスコープのみで宣言され、メインコードx
のデカールには影響しません。x
これは、fn
がオブジェクトでありx
、そのオブジェクトのプロパティであるためです。ローカルスコープは常にグローバルよりも正確です。
fn()のXは関数ですが、グローバルスコープのxは変数です
関数x(){}の部分を削除すると、xにアラートが送信されます10