1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

JavaScriptのスコープ内関数のホイスティングでハマった

Last updated at Posted at 2021-01-10

#ハマった内容

  • ブロックスコープ内の関数はブロックスコープ外から呼び出せる。(ブロックスコープの仕様)
  • 関数はホイスティングされるから、関数の定義より前に関数の呼び出しを書いても、問題なく呼び出せる。(ホイスティングの仕様)

と言うことは、ブロックスコープの外側で、ブロックスコープ内の関数定義より前に呼び出したら、呼び出せるのでは...?(馬鹿)

#結論
ホイスティングは、スコープ内で巻き上げを行うものです。
スコープ外まで巻き上げないので、呼び出せません。
なので、Uncaught TypeError: fn is not a functionとなります。

#ホイスティングとは
JavaScriptの仕様で、スコープの中で、変数や関数が先頭に巻き上げられることです。

###具体例

Example
fn();

function fn() {
    console.log('hoge');
}

/**
 * 出力:hoge
 * 理由:ホイスティングされるので、関数の定義より前に関数を呼び出していても、関数は問題なく実行される。
**/

#ブロックスコープとは
{...}で括られたスコープのことです。
ブロックスコープ内の let / const はブロックスコープ外から参照できません。
function は参照できます。

###具体例

Example2
{
    let a = 0;
    function fn() {
        console.log('hoge');
    }
}
Example2-1
console.log(a);

/**
 * 出力(エラー):Uncaught ReferenceError: a is not defined
 * 理由:ブロックスコープ内の let / const はブロックスコープ外から参照できない
**/
Example2-2
fn();

/**
 * 出力:hoge
 * 理由:funtionは参照できる
**/

#ハマったところ

Example3
fn();
{
    let a = 0;
    function fn() {
        console.log('hoge');
    }
}
/**
 * 出力(エラー):Uncaught TypeError: fn is not a function
 * 理由:ホイスティングはスコープ内が対象のため、ブロックスコープ定義より前からの呼び出しはできない
**/

#まとめ
間違っていたら、コメントで教えていただけると嬉しいです。

1
0
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
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?