javascript - 为什么Javascript引擎每次调用函数都需要创建一个Activation Object?

标签 javascript function scope

总结作用域链的概念:

一旦加载网页,Javascript 就会定位函数定义并为每个定义创建一个所谓的变量对象。 每个 VO 都必须引用每个局部变量(或全局变量),因此从第一个祖先的函数开始,直到全局上下文。 每个函数的作用域链都存储在名为:Scope 的函数属性中。

此外,当一个函数被调用时,一个新对象被创建:一个激活对象

这是什么? :

它就像一个变量对象(实际上它是一个 VO),负责引用所有函数内部的变量对象,包括“arguments”对象和形式参数。

当然,函数祖先的变量对象+函数的Activation Object组成的链中的每一个都首先将至少所有变量映射到undefined。然后,只要执行在进行,它就会通过更新其值(对应于引用的变量)来进化。

但是,我注意到 Activation Object 不同于 Variable Object 的唯一原因是它包含 Arguments 对象,并且这一事实会阻止它在调用函数之前创建。

所以,我想知道为什么构建 Javascript 引擎的人没有在函数的定义步骤分配每个激活对象。因此,当一个函数被调用时,不需要创建它自己的特定激活对象,因为它已经存在了。引擎将在函数执行结束时清除相应的参数对象,以便下一次调用该对象时不会产生副作用。

它可以提高性能吗?事实上,在每次调用时重新创建一个完整的激活对象可能会消耗资源。或者这个提议有问题吗?

最佳答案

激活对象表示函数调用的上下文。每个调用都必须有自己的对象。它们允许关闭等。

将其视为类似于为调用 C 或 C++ 函数分配的堆栈帧。

编辑 — 这是一个示例函数:

function makeCounter( count ) {
  return function() {
    return count++;
  };
}

现在,我可以用它做一个计数器函数:

var counter1 = makeCounter(1);
alert(counter1()); // alerts "1"
alert(counter1()); // alerts "2"

如果我再做一个呢?

var counter100 = makeCounter(100);
alert(counter100()); // alerts "100"

如果对 makeCounter() 的两次调用共享一个 arguments 实例,当我随后调用“counter1()”时会发生什么?

关于javascript - 为什么Javascript引擎每次调用函数都需要创建一个Activation Object?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13139200/

相关文章:

php - 如何将页面附加到自定义帖子类型

javascript - 从不同地方取消setInterval(NodeJS变量范围)

objective-c - Objective-C 中的变量作用域

javascript - 检测jquery版本使用或实时

c++ - 如何将数据传递给多个函数

javascript - 动态链接和 jQuery Lightbox 问题 : Loading image in lightbox. ..完全被难住了!

JavaScript 函数问题

javascript - Function 对象和 ES 模块的范围问题

javascript - 使用 Jquery 即时更改 CSS 类

javascript - 对对象进行排序,使最大的嵌套数组排在前面