【发布时间】:2012-10-30 12:41:06
【问题描述】:
总结作用域链的概念:
加载网页后,Javascript 会定位函数定义并为每个定义创建一个所谓的变量对象。 每个 VO 必须引用每个局部变量(或全局),因此从第一个祖先的函数开始,直到全局上下文。 每个函数的作用域链都存储在名为:Scope 的函数属性中。
此外,当调用函数时,会创建一个新对象:激活对象。
这是什么? :
它就像一个变量对象(实际上它是一个VO),负责引用所有函数内部的变量对象,包括“参数”对象和形参。
当然,函数祖先的变量对象+函数的激活对象组成的链中的每一个首先将至少所有变量映射到undefined。然后,只要执行进行,它就会通过更新其值(对应于引用的变量)来进化。
但是,我注意到激活对象与变量对象不同,仅仅是因为它包含 Arguments 对象,并且这一事实将阻止它在函数被调用之前被创建。
所以,我想知道为什么构建 Javascript 引擎的人没有在函数的定义步骤分配每个激活对象。因此,当调用函数时,无需创建自己的特定激活对象,因为它已经存在。引擎会在函数执行结束时清除相应的参数对象,以便下次调用该对象时不会产生副作用。
它会提高性能吗?实际上,在每次调用时重新创建一个完整的激活对象可能会消耗......或者这个提议有问题吗?
【问题讨论】:
-
我相信从 ECMAScript 5 开始没有“激活对象”。它现在被称为“可变环境”。另外,this excellent article by Angus Croll 可能有助于澄清一些事情。
-
在像 C 这样的旧语言中,“激活记录”是在堆栈上分配的——换句话说,它是“堆栈帧”。在 JavaScript 中,当函数通过实例化一个函数并返回它(或将其绑定到某个全局对象)来公开一个闭包时,激活记录可以在函数调用结束后“存活”。
标签: javascript function scope