Я подведу итог для тех кто наткнётся на этот вопрос через поиск.
1. Неверно дают ответ что мол цикл успевает досчитать до 10. Цикл может продолжаться сколько угодно, но в очереди он стоит первым и поэтому пока он не закончится отложенная функция не сработает. Такая вот асинхронность в js: одна большая очередь за молоком из которой ты можешь только выпасть в самый конец, а асинхронно отойти покурить, а потом попытаться пролезть вперёд какой нибудь бабульки не получится, т.к. огреет бидоном по башке.
2. При создании функция получает скрытое свойство [[Scope]], которое ссылается на лексическое окружение, в котором она была создана. Это свойство никогда не меняется. Оно всюду следует за функцией, привязывая её, таким образом, к месту своего рождения. Поэтому sayHi() выводит "Васю". Как говорится где родился - там и пригодился.