JavaScript es single-thread o monohilo, es decir, toda la ejecución del código se realiza sobre un único hilo. Por eso es muy importante la gestión de la asincronía y los eventos, para no bloquear con tareas pesadas o de larga duración (como una petición Ajax); en caso contrario, se verán efectos como si la UI se quedara "congelada".
Con respecto al setTimeout, no es un problema ese parámetro no informado o con un tiempo cero. Cuando se especifica así:
setTimeout(f, 0);
lo que se está haciendo es planificar la ejecución de ese método lo más inmediatamente posible, pero no se asegura que se ejecute justo en ese momento aunque tenga un valor de cero.
Existe una cola de eventos, que es donde se irían añadiendo o encolando esas ejecuciones planificadas. Cuando el resto del código que está corriendo en el hilo principal ha terminado, lo que ocurre es que la máquina virtual de JS mirará en esa cola de eventos qué función debería ejecutar (si la hubiese). En este caso, como es cero, la función será ejecutada en ese momento.
Una posible utilidad de setTimeout con tiempo cero podría ser para posponer ciertas ejecuciones y que no se vea penalizado una implementación anterior.
Te dejo este vídeo, que a pesar de estar en inglés, se entienden muy bien los conceptos descritos y podrá ayudar mucho en la comprensión.
Si algo no queda claro, deja tu comentario.