「巻き上げ」という概念をご存知だろうか。
これを知らないと思わぬ落とし穴にハマる、ってじっちゃんが言ってたので理解してみた。
巻き上げって?
MDNではこう説明されている。
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements/var
変数の宣言 (および一般的な宣言) はコードを実行する前に処理されますので、変数はコード内のどこで宣言しても、コードの先頭で宣言したものと等価になります。また、変数を宣言する前に変数を使用することもできます。この動作は、変数の宣言が関数やグローバルのコードの先頭に移動したように見えるため、"巻き上げ (hoisting)" と呼ばれます。
ふむふむ?
言葉だけだとピンとこない。
実際に書いてみた
var test = "hoge";
function func() {
console.log(test);
var test = "fuga";
console.log(test);
}
func();
ここでの出力は以下を期待している。
hoge
fuga
が、実際の出力は以下になる。
undefined
fuga
なんで?
グローバル変数で「hoge」を定義しているのになぜ?
となるが、こいつが巻き上げらしい。
変数の宣言 (および一般的な宣言) はコードを実行する前に処理されますので
そしてこいつが原因っぽい。
つまり、さっきのコードは実際には以下のように処理されてしまう。
function func() {
var test; // ここで変数の宣言がされてしまう
console.log(test);
var test = "fuga";
console.log(test);
}
どうすればいい?
グローバル変数を引数として渡してやればOK
var test = "hoge";
function func(test) {
console.log(test);
var test = "fuga";
console.log(test);
}
func(test); // 引数を渡す
期待している通りの結果が返ってきた
hoge
fuga