LoginSignup
5
3

「巻き上げ」の誤解【JS】

Posted at

はじめに

悪名高きvarですが、その理由の一つに「巻き上げ(Hoisting)」があると言われています。

その「巻き上げ」について誤解していたことが多々あったので共有です。

「巻き上げ」は公式の用語ではない

「巻き上げ」は ECMAScript 仕様書で規範的に定義されている用語ではありません。

let constの巻き上げ

varではなく、let constを使え」とよく言われます。
てっきり、let constvarの欠点-巻き上げ-を持たないものと思っていました。
どうも、そう単純な話でもなさそうです。

俗な言い方をすれば、以下のような動作はすべて巻き上げと見なされます。

  1. スコープ内の宣言行よりも前で変数の値を使用すること。(「値の巻き上げ」)
  2. 変数がスコープ内の宣言行よりも前で参照しても ReferenceError が発生せず、値が常に undefined であること。(「宣言の巻き上げ」)
  3. 変数の宣言により、スコープ内のそれが宣言された行よりも前の動作が変化すること。
  4. 宣言の副作用として、宣言を含む残りのコードの評価が行われる前に、宣言の副作用が発生すること。

上記の 4 つの関数宣言はタイプ 1 の動作で巻き上げが行われます。 var 宣言はタイプ 2 の動作で巻き上げが行われます。 letconstclass 宣言(まとめて字句宣言とも呼ばれる)はタイプ 3 の動作で巻き上げが行われます。 import 宣言はタイプ 1 とタイプ 4 の動作で巻き上げが行われます。

また、同じサイトの別ページにはこんな記述もありました。

let と const が巻き上げられるかどうかは、定義の議論の余地があります。変数宣言の前にブロック内で変数を参照すると常に ReferenceError が発生します。ブロックの始まりから宣言が処理されるまで、変数は「一時的なデッドゾーン」にあるからです。

議論の余地がある、という感じですね。
「巻き上げ」が仕様書で定義されている用語でないために起こることですね。

「一時的なデッドゾーン」について知りたい方はこちら

おわりに

以上、巻き上げについて誤解していたことの共有でした。

次は何を書こうかしら・・・

5
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
3