JavaScriptでエラーの原因となるHoisting(巻き上げ)、その仕組みをGIFアニメで分かりやすく解説
Post on:2020年2月27日
JavaScriptでエラーの原因となるHoisting(巻き上げ)はなぜ起こるのか、その仕組みについてGIFアニメーションで分かりやすく解説された記事を紹介します。
🔥🕺🏼 JavaScript Visualized: Hoisting
by Lydia Hallie
下記は各ポイントを意訳したものです。
※当ブログでの翻訳記事は、元サイト様にライセンスを得て翻訳しています。
JavaScript Hoisting(巻き上げ)の仕組みをGIFアニメで分かりやすく解説
Hoisting(巻き上げ)は、JavaScriptでのエラーの原因をGoogleで検索しても分からず、StackOverflowなどで質問した際に目にする用語の1つです。「そのエラーはHoisting(巻き上げ)が原因で発生している🙃」と言われることがあります。
Hoisting(巻き上げ)とは何のことでしょうか?
私は視覚学習者なので、GIFアニメで視覚的に説明することで、あなたの手助けをしようと思います。
JavaScriptにあまり慣れていない場合は、一部の変数がundefinedになったり、ReferenceErrorになったりするなど「奇妙な」動作を経験したことがあるかもしれません。Hoisting(巻き上げ)は変数と関数をファイルの先頭に置くの原因であると説明されることがありますが、実際はそうではありません。動作はそのように見えるかもしれませんが😃
JavaScriptエンジンがスクリプトを取得し最初に行うことは、コード内のデータ用メモリを設定することです。この時点ではコードは実行されず、単に実行するための準備をするだけです。関数宣言と変数の格納方法は異なります。関数は関数全体を参照して格納されます。
関数は関数全体を参照して格納。
変数の場合は少し異なります。
ES6では変数を宣言するために2つの新しいキーワードletとconstが導入されました。letまたはconstで宣言された変数は初期化されずに格納されます。
letとconstで宣言された変数は初期化されずに格納。
varで宣言された変数は、デフォルト値undefinedで格納されます。
varで宣言された変数はundefinedで格納。
作成フェーズが終了したので、実際にコードを実行できます。関数や変数を宣言する前に、ファイルの先頭に3つのconsole.logがあるとどうなるか見てましょう。
関数は関数コード全体を参照して格納されるため、関数を作成した行の前でも呼び出すことができます🔥
実行フェーズではメモリ内の関数全体を参照するため、宣言する前に関数を呼び出せる。
varで宣言された変数を参照すると、格納されたデフォルト値(undefined)を返すだけです。ただし、これにより「予期しない」動作が発生することがあります。ほとんどの場合、これは意図せずに参照していることを意味します(おそらくundefinedという値を持たせたくはないでしょう)😬
varで宣言された変数を参照すると、その値はデフォルト(undefined)になる。
varのようにundefinedを誤って参照することを防ぐために、初期化されていない変数にアクセスしようとすると必ずReferenceErrorが返されます。実際の宣言の前の「ゾーン」はテンポラルデッドゾーン(TDZ)と呼ばれ、初期化の前に変数(ES6のクラスも含まれます)を参照することはできません。
初期化されていない変数にアクセスしようとすると必ずReferenceErrorが返される。これはテンポラルデッドゾーンと呼ばれています。
JavaScriptエンジンが実際に変数を宣言した行を渡すと、メモリ内の値は実際に変数を宣言した値で上書きされます。
変数を宣言した行に渡すと、メモリ内の値が上書きされる。
これで終わりです!🎉
簡単にまとめます。
- 関数と変数は、コードを実行する前に実行コンテキストのメモリに格納されます。これがHoisting(巻き上げ)です。
- 関数は関数全体を参照して格納され、varがundefinedの値を持つ変数、およびletとconstの変数は初期化されずに格納されます。
コードを実行したときに何が起きているのかを見てきたので、Hoisting(巻き上げ)という用語が曖昧にならないことを願っています。いつものように、まだあまり意味が分からなくても心配しないでください。使えば使うほど理解が深まります。
気軽に私に助けを求めてください。私はあなたを助けたいと思います! 😃
sponsors