А если бы это было объявление Function Expression, то такой вызов бы не сработал:
Это из-за того, что JavaScript перед запуском кода ищет в нём Function Declaration (их легко найти: они не являются частью выражений и начинаются со словаfunction) и обрабатывает их. А Function Expression создаются в процессе выполнения выражения, в котором созданы, в данном случае – функция будет создана при операции присваивания sayHi = function....
Как правило, возможность Function Declaration вызвать функцию до объявления – это удобно, так как даёт больше свободы в том, как организовать свой код. Можно расположить функции внизу, а их вызов – сверху или наоборот.
В отличие от объявлений Function Declaration, которые создаются заранее, до выполнения кода, объявления Function Expression создают функцию, когда до них доходит выполнение. Благодаря этому свойству Function Expression можно (и даже нужно) использовать для условного объявления функции.