Обратите внимание, что порядок важен здесь; Вы не можете вызвать bar () перед вызовом foo () в вашем примере. Логика здесь заключается в том, что выполнение foo () определяет bar () и помещает его в глобальную область видимости, но оно не определено до выполнения foo () из-за области видимости.
Использование здесь будет примитивной формой перегрузки функций; ваша функция bar () может выполнять различные операции в зависимости от того, какая версия foo () объявляет ее, при условии, конечно, что каждая отдельная версия foo () действительно определяет функцию bar ().