是对完整代码立即进行提升还是按嵌套函数级别进行提升

Does hoisting takes place at once for the full code or by nested-function-levels

伙计们。我不明白关于提升的事情,这可能是我的错,但我没有找到任何答案,无论是在这里还是 google,这就是我问的原因,感谢阅读。

所以我不明白,当 javascript 引擎获取我的代码并开始扫描时, 将扫描所有函数和嵌套函数的整个代码,直到最后一个范围? 并且所有功能的创建阶段将在第一次扫描时进行(或者换句话说,完整的代码只被扫描一次并为每个功能准备好一切)?

/* Global execution context*/

function myFirst(){ /*Scanner meets this code and hoists it*/
  var A = "12"

  return function myFirstB(){ /*As the scanner arrived here and 
scanns threw this function during the parents hoisting period ( or just before the global contexts execution phase) will it be hoisted  as well, that it gets [[Scopes]] property? So that when I call it in the last line as a closure, it can remember on, that variable "A" is in its outer-environment?*/
      console.log(A) 
    } //myFirstB()

} // myFirst()

function mySecond(){
    alert("one")
}

var myClosure = myFirst();
myClosure(); /*before beeing called does this function have already [[Scopes]] property/scope-chain?*/

还是逐层提升?所以我的意思是首先将提升那些在全局上下文中定义的功能? 然后当其中一个函数被调用并且它的执行上下文执行阶段开始时,它的嵌套函数会被提升吗?

我正在研究这个,因为我真的不明白,嵌套函数是如何记住的,在其中定义了词法 environment/function,如果它至少还没有被提升,它有一个 [[ Scopes]] 属性,它保留了它的作用域链

这个问题是我到目前为止看到的所有文章,甚至 ecmascript 6 文档也只说,如果扫描器满足函数定义,就会发生提升,然后将使用以下内容创建范围 属性作用域链和变量对象参数对象和 "this" 关键字,但我没有找到任何 material 会讨论的,如果嵌套函数(保留在变量对象中,加上引用到它们在内存中的函数体)将至少被提升(同时,它们的父函数被提升)并且因此它们得到一个作用域链以记住它们的外部环境,如果它们从外部调用外部 -环境

感谢大家阅读我的千言万语,如果你能回答或者如果你有一篇文章谈到这方面以及提升,我真的很感激

我看你是因为纠结了太多东西才糊涂的。您需要区分三件事:

  • 解析器的作用
  • 创建范围时会发生什么
  • 代码为 运行
  • 时会发生什么

解析器确实扫描了整个代码。如果任何地方有语法错误,代码的 none 将是 运行。它确实将整个代码解析为适合稍后执行的(嵌套)结构。这可能是 abstract syntax tree 或可执行字节码,或介于两者之间的任何东西 - 这是一个实现细节。

在代码块 运行 之前,例如在全局范围或块范围或函数范围中,必须首先创建和初始化该执行的上下文。它确实获得父作用域引用(例如,块周围的作用域或定义闭包的作用域)、this 值和创建此作用域变量的新变量环境。这里是作用域中声明的所有变量名称(例如函数参数、varfunctionlet 以及 constclass 声明等)的使用位置实例化一个新变量。

当代码块执行statement for statement和expression for expression时,变量已经存在。这是创建值并将其分配给变量的时间。当一个函数被定义时,它确实通过引用当前作用域成为一个闭包。

词条"hoisting"is giving the wrong impression。没有源代码被移动。实现如何实现指定的行为不受限制。可能是解析器创建的字节码在每个范围的顶部创建了变量。可能是在作用域的初始化阶段,它每次都会扫描 AST 以查找声明。它很可能是即时编译器形式的混合,它仅在第一次调用函数时创建字节码。

关于你关于嵌套函数的问题,请记住每次调用外部函数时都会重新创建内部函数。它仅 "hoisted" 到其范围的顶部,不在外部函数之外,并且将在代码的每个 运行 上重新定义。

让我一步步为您解释。

第 1 步(通过解析器):扫描整个代码(所有嵌套级别)以创建 AST(抽象语法树)并检查语法错误。

Step 2 (by JS engine): 提升属于当前关卡的代码。然后执行当前关卡代码。此代码可能有嵌套代码。

第 3 步(通过 JS 引擎):对嵌套代码执行第 2 步。

重复此过程,直到执行所有级别的所有代码。

PS:一些帮助来自