伙计们。我不明白关于提升的一些事情,这可能是我的错,但我没有找到任何答案,这里和谷歌,这是为什么我问,谢谢阅读。
所以我不明白,因为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属性,但我没有找到任何可以讨论的材料,如果嵌套函数(这些函数保存在变量对象中,再加上它们在内存中的函数体)至少会被吊起(同时,他们的父函数被悬挂),所以他们得到了一个关于其外部环境的范围链,如果他们是从外部环境被召唤出来的
非常感谢大家的阅读,如果你能回答我的话,或者你有一篇关于提升的文章,我会很喜欢的。
发布于 2018-04-12 10:16:09
我认为你很困惑,因为你纠结了太多的事情。您需要区分三件事:
解析器确实会扫描整个代码。如果任何地方都有语法错误,则不会运行任何代码。它确实将整个代码解析为一个(嵌套的)结构,适合稍后执行。这可能是一个抽象语法树或可执行的字节码,或者两者之间的任何东西--这是一个实现细节。
在运行代码块之前,比如在全局作用域、块作用域或函数范围中,必须先创建并初始化执行的上下文。它确实获得了父作用域引用(例如,围绕块的作用域或定义了闭包的作用域)、this值以及创建该作用域变量的新变量环境。这里使用范围中声明的所有变量名(例如函数参数、var和function以及let和class声明等)来实例化一个新变量。
在为语句执行代码块和为表达式执行表达式时,变量已经存在。这是当值被创建并分配给变量时。当定义一个函数时,它会通过引用当前作用域而成为一个闭包。
术语“提升”给人错误的印象。没有任何源代码被移动。实现实现指定行为的方式不受限制。解析器可能会创建字节代码,在每个作用域的顶部创建变量。可能是在范围的初始化阶段,它每次都会扫描AST的声明。它很可能是以即时编译器的形式组合而成的,只有在首次调用函数时才会创建字节码。
关于嵌套函数的问题,请记住,每次调用外部函数时,都会重新创建内部函数。它仅被“悬挂”到其作用域的顶部,而不是外部函数之外,并将在代码的每次运行中重新定义。
发布于 2022-03-01 14:05:13
让我一步一步地向你解释。
步骤1(通过解析器):扫描整个代码(所有层次的嵌套)以创建AST (抽象语法树)并检查语法错误。
步骤2(通过JS引擎):仅属于当前级别的提升代码。然后执行当前级别代码。此代码可能有嵌套代码。
步骤3(通过JS引擎):为嵌套代码执行步骤2。
此过程在所有级别上重复,直到执行所有代码为止。
PS:从这个答案那里得到了一些帮助。
https://stackoverflow.com/questions/49792493
复制相似问题