var x = 3;
(function (){
console.log('before', x);
var x = 7;
console.log('after', x);
return ;
})();
上記のコードでは、varXはグローバルに初期化されます。したがって、関数内で最初のconsole.logは「3より前」と出力されるはずですが、取得できません。その理由は、グローバル変数を再宣言しようとしているためです。
なぜこれが起こっているのか誰かが説明できますか?
var x = 3;
(function (){
console.log('before', x);
var x = 7;
console.log('after', x);
return ;
})();
上記のコードでは、varXはグローバルに初期化されます。したがって、関数内で最初のconsole.logは「3より前」と出力されるはずですが、取得できません。その理由は、グローバル変数を再宣言しようとしているためです。
なぜこれが起こっているのか誰かが説明できますか?
上記のコードでは、varXはグローバルに初期化されます。したがって、関数内では、最初のconsole.logは「3より前」と出力する必要があります。
いいえ、出力する必要があります。これは、関数の最初から、どこに書き込んだかに関係なく有効になるbefore undefined
ためです。var
あなたのコードはこれとまったく同じです:
var x = 3;
(function (){
var x;
console.log('before', x);
x = 7;
console.log('after', x);
return ;
})();
そしてもちろん、変数は値で始まりますundefined
。
詳細:誤解が少ないvar
JavaScriptパーサーは、コードを解析するときに変数の巻き上げを行います。これは、変数宣言が現在のスコープの最上位に移動されることを意味します。したがって、この場合、このコードが実行されます。
var x = 3;
(function (){
var x;
console.log('before', x);
x = 7;
console.log('after', x);
return ;
})();
したがって、ローカル変数x
は最初に初期値で宣言されますundefined
。
これは、最初の「beforeundefined」を取得する理由を説明する必要がありますconsole.log()
。
変数のスコープは、他の言語よりもはるかに単純です。宣言からは始まりませんが、次のいずれかです。
MDN:
varで宣言された変数のスコープは、囲んでいる関数です。関数の外部で宣言された変数の場合は、グローバルスコープ(グローバルオブジェクトにバインドされています)です。
すべての変数宣言がスコープ(関数)の先頭に移動されることを想像できます。だからこれはまさに
var x = 3;
(function (){
var x;
console.log('before', x); // now undefined
x = 7;
console.log('after', x); // now 7
return ;
})();
正確なスコープ(ブロックではなく関数)を理解するように注意してください:
var x = 3;
(function (){
console.log('before', x); // this is undefined !
if (true) {
var x = 7;
}
return ;
})();