Essentially your javascript code is compiled down to a data structure called Function which can be called and are stored in a runtime function table.
V8 Doesn't necessarily manage the calling of the callbacks or manage a loop but instead ensures that all execution of its structures happen in the same thread and then relies on the underlying engine to manage work done in background threads and event looping and calling callbacks.
For example nodejs uses libuv for its underlying runtime functionality including the uv_loop_t to manage the actual event looping in the main thread.
As functions are called such as fs.readFile
it will eventually dispatch into a libuv function which takes care to do the work in a background thread and then ultimately takes care to manage the threading involved with pushing that work back into the main event loop.
Essentially the main event loop is a for(;;)
loop that reads these responses out of a queue and continues so long as there are background threads kept alive.
Browsers work in a very similar way but they each have their own implementation of the same concepts.