JavaScriptにおける関数の定義する方法は、以下の4つの方法があります。
- 関数宣言文による定義
- 関数リテラルによる定義
- Functionコンストラクタによる定義
- アロー関数式による定義(ECMAScript6より導入)
今回は、関数宣言文と関数リテラルによる関数の巻き上げについて学習します。
関数の巻き上げ
関数の巻き上げとは関数を宣言する前に使用することを指します。MDNのコードを引用すると、こういういうことですね。hoisted関数はfunctionで定義される前に記述されています。
[php]
hoisted(); // logs "foo"
function hoisted() {
console.log("foo");
}
[/php]
関数の巻き上げについて関数宣言文と関数リテラルの比較
ところでこの関数の巻き上げについて、定義の方法によって使ったり使えなかったりします。GitHubにサンプルコードを用意しました。こちらに基づいて解説を進めていきましょう。
関数宣言文 その1
こちらは先に関数宣言文を定義して、f関数を後に実行しています。コンソールで確認するとそれぞれ、x = 1, y = 2 が返されます。
関数宣言文 その2
こちらは後に関数宣言文を定義して、g関数を先に実行しています。上述したMDNのコードと同じパターンです。それぞれ、x = 3, y = 4 が返されます。
関数リテラル その1
関数リテラルでのため先に関数を定義をし、後にh関数を実行しています。それぞれ、x = 5, y = 6 が返されます。
関数リテラル その2
コンソールで x = 7, y = 8 と返ってきてほしいところですが値は返ってきません。4つの例の中で唯一エラーが返ってきます。i関数を実行すると、Uncaught TypeError: i is not a function が返されます。関数リテラルにおいては、関数を先に宣言しなければならないことが分かります。
JavaScriptでは一口に関数と言っても、いろいろな使い方やお作法があるので、気をつけておきましょう。