Javascript - 上下文执行阶段

时间:2017-10-02 07:25:57

标签: javascript hoisting

我知道JavaScript中的“执行”分两个阶段发生:

1)创建阶段将函数和变量添加到内存中,提升,这是创建和外部环境

2)代码执行的第二阶段。

问题:变量和函数是在脚本启动时还是仅在调用父函数时在内存中添加父函数?

对于这个方面,函数的参数行为和函数内声明的变量之间有什么区别? (我问这个是因为在其他语言中它们表现不同 - 参数在函数执行之前在内存中,但在函数范围内)

2 个答案:

答案 0 :(得分:3)

如果脚本启动时所有函数内的变量和函数都已放入内存,则内存可能在启动时已满。当函数执行时,变量和内部函数被添加到内存中。当函数结束执行时,相关变量将从内存中删除(如果它们未在closure中使用。

  

函数参数的行为之间有任何区别   和在函数

中声明的变量

在行为中没有明显的差别,参数也是在函数范围内声明的变量,只有它们可以从外部获得它们的值。

当您将引用类型传递给函数并在函数中更改其属性时,可能存在一个区别。因此它将在函数本身之外进行更改。这意味着参数可以某种方式限制在外部世界。但我认为这与参数和范围变量的行为无关。它们都是功能范围。

  

参数在函数执行前在内存中,但在   功能范围

Javascript函数可以使用不同数量的参数。所以它无法将参数添加到内存中。你可以拥有一个没有参数的函数,但是调用它并将10个参数传递给它。

答案 1 :(得分:0)

您实际上是在询问依赖于JS引擎内部工作原理的事情。 JavaScript程序可以经历许多阶段,包括“解析”阶段,但实际上,出于不同目的,在不同级别的多个阶段中发生不同类型的解析。 (我不会将其称为“创建”阶段;该术语非标准且令人困惑。)各种解析阶段的结果可以是内部语法树,或中间字节代码表示,甚至是准备好的机器代码执行。相同的代码可能会在不同的时间点以不同的方式进行解析,或者在某些情况下进行解析,然后将结果丢弃并稍后再次重新解析,等等。

重点是,除非你正在学习编译器理论,否则无关紧要。是的,解析可以被认为是“提升”发生的地方。但是,我建议你不要花太多时间担心吊装,除非你打算参加某种JS琐事比赛。只需在每个函数的顶部声明所有变量(包括您分配函数的变量),就像您应该一直在做的那样,然后不再担心它。虽然其他人正在拍拍自己,因为他们知道ES6 class是否被悬挂,你实际上可以编写有用的代码。

分配内存的时间,方式和位置的问题也是内部引擎细节。有些项可能会在“堆”(可能有多个)上分配,然后再进行垃圾回收。这样的分配几乎总是在运行时发生,但这也不是一个严格的规则;例如,在解析期间遇到的regexp可能在堆上以编译形式缓存。其他变量(如基元)可能会在“堆栈”上分配,并在从函数返回时释放堆栈帧时半自动解除分配。需要维护以在嵌入式函数中使用的变量(“闭包”)以特定方式分配和存储。

我怀疑是否知道这一点会让你以任何有意义的方式成为更好的JavaScript程序员。了解一个引擎是如何做到的,并不一定能帮助你理解另一个引擎是如何做到这一点的,甚至也不一定能帮助你理解下一个版本中引擎的工作方式。

除了好奇心,或者您认为会产生影响的具体案例,您是否有特定的理由想要了解这一点?