Название Function Expression (функциональное выражение) дано не просто так. Оно действительно означает это - то, что такие функции являются частью какого-либо выражения.
Например, мы можем сложить какую-нибудь строку и безымянную функцию:
let str = 'str' + function() {return 2;};
alert(str); // выведет 'strfunction() {return 2;}'
Почему мы видим такой странный результат, а не число 3? Потому что второе слагаемое - это не результат работы функции, а ее исходный код (ведь мы эту функцию не вызвали, а просто написали).
То есть название функциональное выражение обозначает то, что такая функция принимает участие в каком-нибудь выражении.
Присваивание к переменной тоже выражение:
let func = function() {
alert('!');
};
Можно также, к примеру, передать функцию в качестве параметра алерта и он выведет ее исходный код на экран - это тоже будет считаться выражением:
alert(function() {return 2;});
Почему это важно: потому что отличие Function Declaration и Function Expression совсем не в том, что первая функция создается с именем, а вторая изначально имени не имеет. Это не так.
Пример. Вот у нас функция без имени, но при этом не участвует ни в каком выражении (то есть с ней не совершается никаких действий, говоря по-простому):
/*
Данная функция будет Function Declaration,
но с синтаксической ошибкой:
*/
function() {
alert('!');
}
Такой код вообще выдаст ошибку! Почему: так как функция не участвует ни в каком выражении, то браузер считает ее Function Declaration, но не находит ее имени и выдает ошибку.
Чтобы ошибка исчезла, нужно заставить функцию
стать частью какого-либо выражения. Например,
напишем перед ней операцию +
:
+function() { // такой код корректен
alert('!');
};
Как это работает: сама по себе операция +
ничего не делает, это все равно как написать
вместо числа 3
число +3
- допустимо,
но ничего не меняет.
Но в случае с функцией - меняет. Теперь наша функция уже не просто написана, а участвует в выражении. Поэтому ошибки теперь не будет. Результата выполнения функции тоже не будет, ведь мы ее просто написали, но не вызвали.
Вместо +
можно написать все, что угодно.
Например:
-function() { // такой код корректен
alert('!');
};
!function() { // такой код корректен
alert('!');
};
Можно также взять нашу функцию в круглые скобки, в этом случае она также станет функциональным выражением:
(function() { // такой код корректен
alert('!');
});
Определите, является ли представленная функция Function Declaration или Function Expression:
function func() {
alert('!');
}
Определите, является ли представленная функция Function Declaration или Function Expression:
let func = function() {
alert('!');
}
Определите, является ли представленная функция Function Declaration или Function Expression:
+function() {
alert('!');
}
Определите, является ли представленная функция Function Declaration или Function Expression:
!function func() {
alert('!');
}
Определите, является ли представленная функция Function Declaration или Function Expression:
-function func() {
alert('!');
}
Определите, является ли представленная функция Function Declaration или Function Expression:
1 + function func() {
alert('!');
}
Определите, является ли представленная функция Function Declaration или Function Expression:
(function func() {
alert('!');
})
Определите, является ли представленная функция Function Declaration или Function Expression:
alert(
function() {
alert('!');
}
);
Функция с именем, но Function Expression
Давайте теперь сделаем функцию, которая будет иметь имя, но при этом будет Function Expression, потому что участвует в выражении:
+function func() {
alert('!');
}
Интересно, что по имени func
мы не
сможем обратиться к нашей функции, это будет
приводить к ошибке:
+function func() {
alert('!');
}
func(); //!! выдаст ошибку
Чтобы иметь возможность вызвать нашу функцию, ее нужно присвоить какой-нибудь переменной:
let test = function func() {
alert('!');
};
test(); // выведет '!'
Еще раз: функция, являющаяся функциональным выражением не может быть вызвана по ее имени. Такая функция может быть вызвана только с использованием переменной, в которую была записана эта функция.
Но тем не менее, функциональное выражение может иметь имя функции, это будет синтаксически корректно. Зачем такое нужно, мы будем разбираться в следующих уроках.
Выводы
Подведем итог: функции являются Function Declaration или Function Expression не потому, что имеют имя или не имеют, а потому, что являются участниками выражений или не являются.
Как вы видели выше, функция без имени может быть воспринята как Function Declaration, а функции с именем может быть Function Expression.
Как проверить тип функции
В задачах ниже вам нужно будет определить функция определена как Function Declaration или Function Expression.
В простых случаях это не составляет труда сделать визуально. Но как проверить, что вы сделали это правильно? Используйте разницу между Function Declaration или Function Expression: первые могут быть вызваны выше своего определения, а вторые - нет.
Пусть у нас есть вот такая функция:
let test = function() {
alert('!');
}
Обратимся к этой функции до ее определения:
test(); // выведет ошибку в консоль, значит Function Expression
let test = function() {
alert('!');
}
Вот еще пример:
func(); // выведет '!', значит Function Declaration
function func() {
alert('!');
}
Поставим перед нашей функцией плюсик:
func(); // выведет ошибку в консоль, значит Function Expression
+function func() {
alert('!');
}
Так как функция выше - это Function Expression и она не присвоена никакой переменной, то ее никак не вызвать, ведь по имени func она будет недоступна.
Определите, является ли представленная функция Function Declaration или Function Expression:
let test = function func() {
alert('!');
}
Определите, является ли представленная функция Function Declaration или Function Expression:
alert(
function func() {
alert('!');
}
);
Определите, является ли представленная функция Function Declaration или Function Expression:
+function func() {
alert('!');
}
Определите, является ли представленная функция Function Declaration или Function Expression:
function func() {
alert('!');
}
Более сложные нюансы
Давайте рассмотрим следующий код:
+function func() {
alert('!');
}
Как вы уже знаете, эта функция является функциональным выражением, ни смотря на то, что у нее задано имя (мы уже выяснили, что наличие имени вообще не критерий). Уберем этот плюс - и получим Function Declaration:
function func() {
alert('!');
}
Давайте поставим +
на строчке перед
функцией - она опять станет Function Expression:
+
function func() {
alert('!');
}
А теперь после плюса поставим число 1
и точку с запятой - наша функция станет Function
Declaration:
+1;
function func() {
alert('!');
}
Почему так: потому что на первой строке написана одна законченная команда, закрытая точкой с запятой. Поэтому эта команда никак не влияет на нашу функцию.
На самом деле точку с запятой можно убрать, ведь в JavaScript она не обязательна - функция все равно останется Function Declaration:
+1
function func() {
alert('!');
}
А вот если после 1
влепить еще один
плюс, то функция станет Function Expression:
+1+
function func() {
alert('!');
}
Почему так: потому что на первой строчке незавершенное выражение - стоит плюс и после него ничего. Поэтому интерпретатор JavaScript считает, что этот плюс относится к строке ниже, то есть к нашей функции.
Если же на первой строке стоит завершенное выражение, то JavaScript автоматически ставит ему точку с запятой и это выражение никак не влияет на нашу функцию.
Определите, является ли представленная функция Function Declaration или Function Expression:
-
function func() {
alert('!');
}
Определите, является ли представленная функция Function Declaration или Function Expression:
-1;
function func() {
alert('!');
}
Определите, является ли представленная функция Function Declaration или Function Expression:
-1
function func() {
alert('!');
}
Определите, является ли представленная функция Function Declaration или Function Expression:
1
function func() {
alert('!');
}
Определите, является ли представленная функция Function Declaration или Function Expression:
-1-
function func() {
alert('!');
}
Выражение справа
Учтите, что выражение, в котором участвует функция, должно быть слева от нее. Если мы что-то пытаемся сделать справа от функции, это не сделает ее функциональным выражением. Пример:
function func() { // это Function Declaration
alert('!');
} + 1;
Почему так: потому что в данном случае этот +1 является просто новой командой, написанной после функции. Если написать эту команду с новой строки, все становится очевиднее:
function func() {
alert('!');
}
+1; // просто команда
Сделаем из нашей функции Function Expression.
Например, поставим перед функцией +
:
+function func() { // это Function Expression
alert('!');
} + 1;
Или выполним присваивание:
let test = function func() { // это Function Expression
alert('!');
} + 1;
Или передадим параметром в алерт:
alert(function func() { // это Function Expression
alert('!');
} + 1);
Определите, является ли представленная функция Function Declaration или Function Expression:
function func() {
alert('!');
}
+1;
Определите, является ли представленная функция Function Declaration или Function Expression:
function func() {
alert('!');
} + 1;
Определите, является ли представленная функция Function Declaration или Function Expression:
+function func() {
alert('!');
} + 1;
Определите, является ли представленная функция Function Declaration или Function Expression:
+
function func() {
alert('!');
} + 1;
Определите, является ли представленная функция Function Declaration или Function Expression:
+ 1
function func() {
alert('!');
} + 1;
Определите, является ли представленная функция Function Declaration или Function Expression:
function func() {
alert('!');
} + alert('!');