Именованные функциональные выражения в 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 с именем функции называются именованными функциональными выражениями.