Расскажите что там в основе происходит? Неужели функция лежащая в переменной уже не функция - в основах?
Строка alert(counter()) разбирается парсером в инструкции виртуальной машины по спецификации языка (в отдельных случаях это будет компиляция сразу в машинный код, но отбросим это для простоты). Последовательность этих инструкций выглядит в упрощённом виде примерно так:
1. найти объект counter в области видимости
2. применить операцию [Call] к объекту с пустым списком аргументов
3. результат операции сохранить
4. Найти объект alert в области видимости
5. Применить операцию [Call] к объекту, в качестве списка аргументов передать список из одного элемента - результата вызова counter