在 javascript V8 中,编译阶段是否发生在执行阶段之前的函数上,然后执行所有代码或仅针对全局上下文

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

我读过很多文章说编译(创建)阶段首先发生在全局执行上下文中,然后代码被执行,当调用一个函数时,创建阶段再次开始这个函数,然后它被执行 这真的是正在发生的事情吗?为什么所有代码​​的创建阶段都没有发生,首先包括函数内部的变量,然后执行所有代码,因为像这样创建阶段是执行阶段本身的一部分,并且引擎在执行之前不知道函数内部有哪些变量阶段 另外,如果是这样,为什么这样的事情会在不先登录控制台的情况下给出错误

console.log('First No Error')

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

Error()

它给出了参考错误,因为没有先登录到控制台(无错误)就没有定义 z 为什么会发生这种情况,因为引擎不应该知道函数内部存在错误,直到函数仅在最后一行执行。

我想知道函数内部知道什么,并且可以在函数本身执行之前使用它(即使它只是内存中没有真实数据的引用,当它成为内存中的真实数据时)。

(此处为 V8 开发人员。)

compilation(creation) phase

这是两个不同的东西。 “创建阶段”是一些人为了向其他人(比如您)解释 JavaScript 引擎的作用而提出的概念。如果您发现它比帮助更令人困惑,您应该直接向他们反馈 :-)

“编译”是一个 engine-internal 实现细节:一些引擎可能会将 JavaScript 源代码编译为字节码或机器码或两者,其他引擎可能不会; JavaScript 语言规范对此没有意见。您在现代浏览器中找到的 JavaScript 引擎都进行各种形式的编译和重新编译;细节取决于每个引擎,并且会不时更改。在基于编译思想构建的引擎中,编译必须在执行之前发生(因为编译的结果将被执行),但多长时间并不重要:它可能发生在第一次执行之前,或者很久以前了。

JavaScript 规范确实要求引擎在看到代码时立即报告某些错误(“早期错误”)。所以引擎确实必须立即查看所有代码,至少要找到这些类型的错误。但这与编译任何东西都不一样。 (并且 console.log(z) 不是早期错误的示例。)

JavaScript 引擎喜欢将任何不需要的工作推迟到以后,以保持快速启动。让网站加载得更快是一种更好的用户体验,因为页面加载通常只涉及页面的一些资源(例如:只有一些 JS 函数被调用,只有一些图像被显示),这是浏览器加速的一种方式up 页面加载是通过只做加载所必需的:像编译那些只会稍后调用的函数,下载那些只会稍后显示的图像,可以推迟到实际需要时。

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

事实并非如此;在抛出 ReferenceError 之前记录“First No Error”。试试看!

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

在相应代码运行时创建对象并初始化变量。当您 定义 函数时,您可以引用函数外部(词法)作用域中的任何变量。例如:

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;