1

嘿伙计们。我不明白关于吊装的一些事情,这可能是我的错,但我没有找到任何答案,无论是在这里还是在谷歌上,这就是我问的原因,感谢阅读。

所以我不明白,当 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?*/

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

我正在调查这个问题,因为我真的不了解嵌套函数是如何记住的,它是在哪个词法环境/函数中定义的,如果它至少没有被提升,它有一个 [[Scopes]] 属性,它保留它的范围链

问题是我到目前为止看到的所有文章,甚至 ecmascript 6 文档也只说,如果扫描仪满足函数定义a,那么会发生提升,然后范围属性将使用范围链和变量对象创建,参数对象和“this”关键字,但我没有找到任何可以谈论的材料,如果嵌套函数(保存在变量对象中,并在那里加上对其在内存中的函数体的引用)至少也会被提升(同时,他们的父函数被提升)并且他们得到一个作用域链来记住他们的外部环境,如果他们从那里被外部环境调用

非常感谢阅读我的大量文字,如果你能回答它或者如果你有一篇关于这方面以及提升的文章,我真的很感激

4

2 回答 2

2

我觉得你很困惑,因为你纠结的东西太多了。你需要区分三件事:

  • 解析器做什么
  • 创建范围时会发生什么
  • 代码运行时会发生什么

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

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

当代码块以语句为语句和表达式为表达式执行时,变量已经存在。这是创建值并将其分配给变量的时间。当一个函数被定义时,它确实通过引用当前范围成为一个闭包。

“吊装”一词给人的印象是错误的。没有源代码被移动。实现如何实现指定行为不受限制。可能是解析器创建的字节码在每个作用域的顶部创建了变量。可能是在作用域的初始化阶段,它每次都会扫描 AST 中的声明。它很可能是即时编译器形式的混合,它仅在第一次调用函数时创建字节码。

关于您关于嵌套函数的问题,请记住每次调用外部函数时都会重新创建内部函数。它只是“提升”到其范围的顶部,而不是外部函数之外,并且将在每次运行代码时重新定义。

于 2018-04-12T10:16:09.440 回答
0

让我一步一步地向你解释。

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

第2步(通过JS引擎):仅提升属于当前级别的代码。然后执行当前级别的代码。此代码可能有嵌套代码。

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

这个过程重复,直到所有代码都被执行,所有级别。

PS:从这个答案中获得了一些帮助。

于 2022-03-01T14:05:13.777 回答