Javascript - 上下文执行阶段

Javascript - Context Execution phases

我知道 JavaScript 中的 "execution" 分两个阶段进行:

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

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

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

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

如果脚本启动的时候所有函数里面的变量和函数都被放到了内存中,那么你的内存在启动的时候可能就满了。当一个函数执行时,此时变量和内部函数被添加到内存中。当函数结束执行时,如果相关变量没有在 closure.

中使用,则相关变量将从内存中删除

There is any difference between behavior of parameters of a function and variables declared inside function

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

一个区别可能是当您将引用类型传递给函数并在函数中更改其 属性 时。所以它会在函数本身之外被改变。这意味着可以通过某些方式将参数绑定到 外部世界。但我认为这与参数和作用域变量的 行为 无关。它们都在函数范围内。

the parameters are in memory before function executes, but in the scope of function

Javascript 函数可以采用不同数量的参数。所以它不能将参数添加到内存中。你可以有一个没有参数的函数,但调用它并向它传递 10 个参数。

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

重点是,除非您正在学习编译器理论,否则没关系。是的,解析可以被认为是 "hoisting" 发生的地方。但是,我劝你不要花太多时间担心提升,除非你打算参加某种 JS 琐事竞赛。只需在每个函数的顶部声明所有变量(包括您为其分配函数的变量),就像您一直应该做的那样,然后就不用再担心了。当其他人因为知道 ES6 classes 是否被提升而自鸣得意时,您实际上可以编写有用的代码。

何时、如何以及在何处分配内存的问题也是一个内部引擎细节。某些项目可能会在 "heap" 上分配(其中可能不止一个),然后在以后进行垃圾收集。这种分配几乎总是发生在 运行 时间,但这也不是一成不变的规则;例如,在解析过程中遇到的正则表达式可能会以已编译的形式缓存在堆上。其他变量,例如原语,可能会在 "stack" 上分配,并在从函数返回时释放堆栈帧时半自动取消分配。需要维护以用于嵌入式函数的变量 ("closures") 以特定方式分配和存储。

我怀疑了解其中的任何内容是否会让您以任何有意义的方式成为更好的 JavaScript 程序员。了解一个引擎如何工作不一定能帮助您了解另一个引擎如何工作,甚至不一定能帮助您了解同一引擎在下一个版本中的工作方式。

除了好奇之外,您是否有特定的原因想知道这一点,或者您认为它会产生影响的特定情况?