首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >提升是为完整的代码同时进行,还是由嵌套函数级别进行。

提升是为完整的代码同时进行,还是由嵌套函数级别进行。
EN

Stack Overflow用户
提问于 2018-04-12 09:10:16
回答 2查看 583关注 0票数 1

伙计们。我不明白关于提升的一些事情,这可能是我的错,但我没有找到任何答案,这里和谷歌,这是为什么我问,谢谢阅读。

所以我不明白,因为javascript引擎在下面得到我的代码并开始扫描,会是所有函数和嵌套函数扫描抛出的全部代码吗,直到最后一个范围?所有函数的创建阶段将在第一次扫描时进行(或者用其他的话说,完整的代码是否只扫描一次,并为每个函数准备好一切)?

代码语言: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文档也只说,如果扫描器符合函数定义,然后用范围链和变量对象参数对象和"this“关键字创建scope属性,但我没有找到任何可以讨论的材料,如果嵌套函数(这些函数保存在变量对象中,再加上它们在内存中的函数体)至少会被吊起(同时,他们的父函数被悬挂),所以他们得到了一个关于其外部环境的范围链,如果他们是从外部环境被召唤出来的

非常感谢大家的阅读,如果你能回答我的话,或者你有一篇关于提升的文章,我会很喜欢的。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-04-12 10:16:09

我认为你很困惑,因为你纠结了太多的事情。您需要区分三件事:

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

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

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

在为语句执行代码块和为表达式执行表达式时,变量已经存在。这是当值被创建并分配给变量时。当定义一个函数时,它会通过引用当前作用域而成为一个闭包。

术语“提升”给人错误的印象。没有任何源代码被移动。实现实现指定行为的方式不受限制。解析器可能会创建字节代码,在每个作用域的顶部创建变量。可能是在范围的初始化阶段,它每次都会扫描AST的声明。它很可能是以即时编译器的形式组合而成的,只有在首次调用函数时才会创建字节码。

关于嵌套函数的问题,请记住,每次调用外部函数时,都会重新创建内部函数。它仅被“悬挂”到其作用域的顶部,而不是外部函数之外,并将在代码的每次运行中重新定义。

票数 2
EN

Stack Overflow用户

发布于 2022-03-01 14:05:13

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

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

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

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

此过程在所有级别上重复,直到执行所有代码为止。

PS:从这个答案那里得到了一些帮助。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49792493

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档