Be the JavaScript interpreter.
Let's see the list of tasks, the JavaScript interpreter have to do :
TaskList
[Execute main code]
Now the interpretor execute the task, line by line.
Executing foobar(); the JavaScript interpreter is going to push a new task in it's task list, which is containing the setTimeout() function to execute.
TaskList
[Execute main code (in progress)][Execute setTimeout function]
Then when it reach the throw, it throw an error and terminate the actual task execution.
It takes the next task and execute it :
TaskList
[Execute setTimeout function (in progress)]
Executing the setTimeout function, it pushes again a new task (the same it just executed).
And again, and again, and again, and again...
function foobar() {
console.log('baz');
setTimeout(() => foobar(), 1000);
}
foobar();
throw new Error('terminate');