Так. В первую очередь, изучайте, что такое стек вызовов (call stack).
Call stack можно рассматривать как коробку книг, куда можно положить сколько угодно книжек, но читать можно книгу, которая лежит поверх всех книг. Как закончим читать, можем достать уже следующую и так до конца. Работает он по принципу LIFO (Last In First Out, последним пришел - первым ушел).
Когда функция вызывается, она создает запись в стеке вызовов, в которой лежат её аргументы и локальные переменные. Эту запись называют stack frame (стековый кадр). Когда функция вызывает другую функцию, в call stack вставляется новый кадр, уже поверх старого. Как только эта функция заканчивает свою работу, запись из стека удаляется и следующая функция продолжает свою работу и в конце её фрейм тоже удаляется.
В общем, эту тему можно очень глубоко изучать в интернете.
У вас функция работает так:
Изначально вы выводите число в консоль, потом рекурсивно вызываете эту функцию в блоке else с аргументом num -1, дальше снова выводите это число в консоль. То есть, вы выводите каждое число по два раза, но поскольку рекурсия забивает call stack, у вас получается такой "странный" вывод. Уберите console.log из else и картинка поменяется.