总结作用域链的概念:
一旦加载网页,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/