@minop1205概要とりあえず問題なぜこうなるのか?まとめと予防策JavaScriptには、他の言語ではあまり聞かない(あるいは存在しない)「変数の巻き上げ(hoisting)」という概念があります。これは(たぶん)JavaScript特有のもので、かつ重要なポイントです。この「変数の巻き上げ」が原因でコードが思った通りの動作をしなかった場合、この概念を知らないと、いくらコードを見直しても問題を発見することができません。いう意味でも、この「変数の巻き上げ」の概念をおさえておくことは重要です。変数の巻き上げを説明するには、文章で説明するよりもコードを見てもらった方が理解できると思います。次のコードを見てください。//出力内容は?}func();上記のコードの4行目と6行目の出力内容はどうなるでしょうか?おそらく、最初のconsole.logが”global”、そして次のconsole.logが”local”と思った方も多いと思います。これはもっともな予想ですね。他の言語の概念からすればそれが正解になると思います。JavaScriptでは違います。正解は最初のconsole.logが”undefined“、次のconsole.logが”local“になります。出力される、と考えてしまいます。ならなかったのでしょうか?なぜこうなるのか?JavaScriptでは、関数内のどこにでもvar文を使用して変数を宣言することができます。これらの変数は関数内のいかなる場所で宣言されたとしても、その関数の先頭で宣言されたのと同じように動作します。JavaScriptでは、関数内で宣言されたローカル変数は、すべてその関数の先頭で宣言されたものとみなされる。このような振る舞いは「変数の巻き上げ(hoisting)」と呼ばれます。先ほどのコード例は、実際には以下のコードと同じ振る舞いとなります。"local";が巻き上げられ、関数の先頭で宣言されたように扱われます。“local”)の代入までは行われません。undefined;と同じ意味ですので、最初のconsole.logでは「undefined」が出力された、ということです。変数の巻き上げはJavaScript特有の概念です。いっても、この「変数の巻き上げ」をコーディング中に常に意識しておく必要があるかというと、実はそんなことはありません。要は変数の巻き上げが起きないようなコードを書くようにすればよいのです。方法はいたって簡単で、関数の中で使用されるすべてのローカル変数を関数の先頭で宣言するだけです。関数で使用されるローカル変数は、関数の先頭で宣言する!こうすれば、関数内で「変数の巻き上げ」は起こり得ません。変数を関数の先頭で宣言することは、コードの見通しを良くすることにも役立ちます。書かなくてはならない場合は、JavaScriptにおけるコーディングパターンの一つである「単独varパターン」を使用することにより、よりすっきりとコーディングを行うことが可能になります。(単独varパターンについては、こちらで詳しく紹介しています。)「変数の巻き上げ」にメリットなどありません。予期せぬ巻き上げは意図しない結果をもたらす場合もあるため、JavaScriptコーディングの際はこの「巻き上げ」が起こらないようなコーディングをすべきだと思います。それには、「関数の先頭ですべてのローカル変数を宣言する」というだけのとても簡単でシンプルな解決方法があります。これに関連したコーディングパターンである「単独varパターン」についても、導入しやすく、かつ推奨されているパターンですので、是非実践してみてくださいね。2016年9月30日サイトマップ。