Skip to content
Advertisement

In javascript V8 does compilation phase happen to functions before execution phase then all the code is executed or only for global context

I read many articles saying that compilation(creation) phase happens first to the global execution context then the code is executed and when a function is invoked the creation phase then begins again for this function and then it is executed is this really what is happening? why creation phase is not happening for all of the code first including variables inside functions then all of the code is executed because like this the creation phase is part of the execution phase itself and the engine do not know what variables inside the function until the execution phase Also if so why something like this gives error without logging to the console first

console.log('First No Error')

function Error() {
  let a = 2
  console.log(z)
}

Error()

It gives reference error as z is not defined without logging to the console (No Error) first why this is happening as the engine should not know that there is an error inside a function until it is executed at the last line only.

I want to know what is known inside the function and one can use it(even if it just a reference without real data in memory and when it becomes real data in memory) before the function itself is executed.

Advertisement

Answer

(V8 developer here.)

compilation(creation) phase

Those are two different things. The “creation phase” is a concept that some people have come up with in order to explain to other people (like you) what a JavaScript engine does. If you find it more confusing than helpful, you should probably direct that feedback at them 🙂

“Compilation” is an engine-internal implementation detail: some engines might compile JavaScript source to bytecode or machine code or both, others might not; the JavaScript language specification has no opinion on this. The JavaScript engines you find in modern browsers all do various forms of compilation and recompilation; the details are up to each engine and change every now and then. In an engine that’s built on the idea of compilation, compilation has to happen before execution (because it’s the result of the compilation that will get executed), but it doesn’t matter how long: it could happen right before the first execution, or a long time before it.

The JavaScript specification does require engines to report certain errors (“early errors”) immediately when seeing the code. So engines do have to look at all the code right away, at least to find these kinds of errors. But that’s not the same as compiling anything. (And console.log(z) is not an example of an early error.)

JavaScript engines like to postpone any work that isn’t needed yet until later in order to keep startup fast. Having web sites load faster is a better user experience, and since page load typically only involves some of the page’s resources (e.g.: only some of the JS functions get called, only some of the images are displayed), one way how browsers can speed up page load is by only doing what’s necessary for the load: work like compiling those functions that will only get called later, and downloading those images that will only get shown later, can be postponed until it is actually needed.

It gives reference error as z is not defined without logging to the console (No Error) first why this is happening

That is not what’s happening; “First No Error” is logged before the ReferenceError is thrown. Try it and see!

I want to know what is known inside the function and one can use it before the function itself is executed.

Objects are created and variables are initialized when the respective code runs. When you define a function, you can refer to any variables in the function’s outer (lexical) scope. For example:

function f1() {
  console.log(a);  // This will be fine.
  console.log(b);  // This will be an error (at execution time).
  console.log(c);  // This will be an error (at execution time).
  console.log(d);  // This will log 'undefined'.
}

// This is in f1's outer scope, so f1 can use it.
// For better readability, I would recommend to define variables like `a`
// before defining the functions that use them (like f1), but that's not
// a JavaScript requirement, just a recommendation for human readers.
var a = 42;

function f2() {
  var b = 123;  // This is not in f1's outer (lexical) scope.
  f1();
}
f2();

// This is in f1's outer scope, but only created after f1 is called.
// Contrary to `var` variables, `let` variables are not hoisted to the
// beginning of their scope, so are (sort of) "invisible" before.
let c = 77;
// f1 will be able to see the existence of this variable, but its value
// will only be set after the call (when execution reaches this point here),
// so within f1 it will be `undefined`.
var d = 88;
Advertisement