Причина в том, что код ECMAScript обрабатывается.
Во время инициализации сначала обрабатываются объявления функций, а затем объявления переменных (процесс, часто называемый "подъем"). Затем начинается выполнение.
Выражения функций вычисляются во время выполнения.
Таким образом, вы не можете сразу выполнять объявления функций, потому что даже переменных еще не существует, а другой код, который функция может зависеть от hasnлибо не были выполнены.
Рассмотрим что-то простое:
foo(); // shows undefined
var randomNumber = function() { // function expression
return Math.random();
}(); // () makes it an IIFE
foo(); // shows value assigned to randomNumber
function foo() { // function declaration
alert(randomNumber);
}
Функция foo существует до randomNumber (несмотря на последовательностькод), поэтому попытка выполнить его немедленно приведет к ошибке ссылки. После завершения инициализации были объявлены foo и randomNumber .
Код RHS присвоения randomNumber анализируется во времяинициализация для синтаксических ошибок, но не выполняется до фазы выполнения.
Теперь начинается выполнение, выполняется выражение функции и присваивается значение randomNumber , поэтому, когда foo равно randomNumber существует и имеет любое значение, возвращаемое выражением функции в RHS.