JavaScriptにおける名前付き関数式

次のような関数式があるとします:

javascriptlet test = function() {
  console.log('!');
};

test(); // '!'と出力する

この関数にfuncという名前を付けてみましょう:

javascriptlet test = function func() {
  console.log('!');
};

test();

ご存知の通り、この名前では関数を参照できません:

javascriptlet test = function func() {
  console.log('!');
};

test(); // '!'と出力する
func(); // エラーが発生する

では、なぜアクセスできない名前を付けるのでしょうか?その理由は、この名前は関数の外部からは利用できませんが、関数の内部からは利用できるからです。

確認してみましょう:

javascriptlet test = function func() {
  console.log(func); // 関数は自身のソースコードを出力する
};

test(); // 関数を呼び出す

関数の内部で自身を呼び出してみましょう:

javascriptlet test = function func() {
  console.log('!'); // '!'を出力
  func(); // 自身を呼び出す
};

test();

このコードを実行すると、コンソールに無限に出力が行われます。

実際、この関数は内部でfuncとしてだけでなく、testとしても呼び出すことができます:

javascriptlet test = function func() {
  console.log('!');
  test(); // 自身を呼び出す
};

test();

違いは何でしょうか?違いは、名前testは単なる変数だということです。スクリプトの実行中に、この関数が別の変数に代入されたり、パラメータとして渡されたりする可能性があります。その場合、変数testと関数の関連性が失われる可能性があります。

一方、名前funcは、関数の内部から自身を参照できるようにするために、関数に厳密に紐付けられています。

このような名前が付いたFunction Expressionは、名前付き関数式と呼ばれます。