Хотя оба они служат одинаковым целям, между этими двумя типами объявлений есть разница. Проверьте следующий пример:
//Function expression functionOne(); //Error //"TypeError: functionOne is not a function var functionOne = function() { console.log("functionOne"); }; //Function declaration functionTwo(); //No error //Prints - functionTwo function functionTwo() { console.log("functionTwo"); }
Объявление функции
обрабатывается, когда выполнение входит в контекст, в котором оно появляется до выполнения любого пошагового кода. Создаваемой функции присваивается собственное имя (functionTwo()
в предыдущем примере), и это имя помещается в область, в которой появляется объявление. Поскольку он обрабатывается перед любым пошаговым кодом в том же контексте, вызов functionTwo()
перед его определением работает без ошибок.
Однако functionOne()
— это выражение анонимной функции, оцениваемое при достижении его при пошаговом выполнении кода (также называемом выполнением во время выполнения); мы должны объявить его, прежде чем мы сможем его вызвать.
Таким образом, объявление функции functionTwo()
было поднято, в то время как функциональное выражение functionOne()
выполнялось, когда оно встречалось при построчном выполнении.
ПРИМЕЧАНИЕ:
Поднимаются как объявления функций, так и объявления переменных, но сначала поднимаются функции, а затем переменные.
Следует помнить, что вы никогда не должны использовать объявления функций условно. Это поведение не стандартизировано и может вести себя по-разному на разных платформах. В следующем примере показан такой фрагмент, в котором мы пытаемся условно использовать объявления функций. Мы пытаемся назначить другое тело функции для функции sayMoo()
, но такой условный код не гарантирует работу во всех браузерах и может привести к непредсказуемым результатам:
// Never do this - different browsers will behave differently if (true) { function sayMoo() { return 'trueMoo'; } } else { function sayMoo() { return 'falseMoo'; } } foo();
Однако совершенно безопасно и разумно сделать то же самое с функциональными выражениями:
var sayMoo; if (true) { sayMoo = function() { return 'trueMoo'; }; } else { sayMoo = function() { return 'falseMoo'; }; } foo();
Если вам интересно узнать, почему не следует использовать объявления функций в условных блоках, читайте дальше; в противном случае вы можете пропустить следующий абзац.
Объявления функций могут появляться только в теле программы или функции. Они не могут появляться в блоке ({ ... }
). Блоки могут содержать только операторы, а не объявления функций. Из-за этого почти все реализации JavaScript имеют отличное от этого поведение. Всегда рекомендуется никогда не использовать объявления функций в условном блоке.
Функциональные выражения, с другой стороны, очень популярны. Очень распространенный шаблон среди программистов JavaScript — разветвление определений функций на основе некоторого условия. Поскольку такие ответвления обычно происходят в одной и той же области видимости, почти всегда необходимо использовать функциональные выражения.