Почему данный код сработает?
Потому что когда вы пишете a = 2, не объявляя ее, значение записывается в глобальную переменную a. Если внутри функций заменить a = 2 на let a = 2, поведение поменяется.
Да, ответ выше правильный, потому что без var или let. А вот после функций есть var a, то это объявление переменной поднимается вверх перед выполнением всего скрипта, но в а ничего не записывается, а запишет значение функция.