LoginSignup
0
0

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

Last updated at Posted at 2024-04-14

はじめに

先日、以下の記事にてvar const letを対象とした巻き上げについて調べました。

するとfunctionでも同様の現象が見られると教えていただきました。
今まで疑問だった、function f() {}const f = () => {}の違いのひとつらしいです。検証してみましょう。

期待する挙動

1. constを使うと、期待するエラーを示す

functionを定義する際、constを使うと正常にエラー(ReferenceError: Cannot access before initialization)を吐くが、constを使わないとundefinedを示す。

つまり、

f()
const f = function () {
  console.log('const_function!')
}

はエラーを吐くが、

f()
function f() {
  console.log('function!')
}

これはundefinedを示す

2. アロー関数でも代入でも挙動が変わらない

今回の論点において、以下の2つの挙動が変わらないこと(どちらもReferenceError: Cannot access 'cf' before initializationを返す)

f()
const f = function () {
  console.log('const_function!')
}
f()
const f = () => {
  console.log('const_allow_function!)
}

検証結果

ほぼ期待通りでした。

(具体的な検証手順は後に示します)

  1. constを使うと、期待するエラーを示す
    →期待通り、constを使用するとReferenceError: Cannot access 'f' before initializationを返しました。
    期待と違ったのは、constを使用しないケースです。undefinedを示すのではなく、正常にfunction fが動作しました。

  2. アロー関数でも代入でも挙動が変わらない
    →期待通り、constを使用する2パターンでは、どちらもReferenceError: Cannot access 'f' before initializationを示しました。

検証手順

1. constを使うと、期待するエラーを示す

まず、以下のコードを実行し、一般的な記法での挙動を確認しました。

f()

function f() {
  console.log('function!');
}

出力

function!

undefinedを期待していましたが、なんと普通に動作しました。
それ定義してるの、未来の話なんだけど・・・と、タイムスリップしてる気分。

次に、以下のコードを実行し、constを使用したケースの挙動を確認しました。

cf()

const cf = function() {
  console.log('const_function!')
}

出力

cf()
^

ReferenceError: Cannot access 'cf' before initialization

こちらは期待通り、ReferenceError...before initializationを吐いてくれました。

最後に、以上の2つを並べて実行してみました。

f()

function f() {
  console.log('function!');
}

cf()

const cf = function() {
  console.log('const_function!')
}

出力

function!
/home/runner/testtdz/hoisting_of_function.js:7
cf()
^

ReferenceError: Cannot access 'cf' before initialization

f()の結果であるfunction!が出力された後、cf()のエラーであるReferenceError...before initializationが表示されていますね。

2. アロー関数でも代入でも挙動が変わらない

先程検証していない「アローバージョン」を実行してみました。

caf()

const caf = () => {
  console.log('const_allow_function!');
}

出力

caf()
^

ReferenceError: Cannot access 'caf' before initialization

予想通り、アローバージョンでもReferenceError...before initializationを出力しました。
やったね。

おわりに

以上、functionの巻き上げについての仮説・結果・検証方法でした。

長年の疑問だったconst f = () => {}function() {}の明確な違いがあったのは個人的大発見です。
やはりアロー・・・アローはすべてを解決する・・・!

さて、次は何を書こうかしら・・・

0
0
2

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