Take a look at the following schematic of Google's V8:

The code is parsed first, which means it is translated into tokens, which form an abstract syntax tree. That tree is fed to an interpreter, which can do stuff, like hoisting and in general will provide an un-optimized JIT compilation (because that's really quick!). While the code runs, it is analysed and especially often executed code is sent to TurboFan for an optimized compilation. The un-optimized code is then replaced by optimized code. It's one of many tricks to get the fastest JS experience into the browser.
Firefox does something similar in the latest version for WASM (however, regular JS just needs the additional parser step). They released a pretty interesting read on it, which might help you further understand modern JS code interpretation and compilation ;)