Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/411.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么每次调用函数时Javascript引擎都需要创建激活对象?_Javascript_Function_Scope - Fatal编程技术网

为什么每次调用函数时Javascript引擎都需要创建激活对象?

为什么每次调用函数时Javascript引擎都需要创建激活对象?,javascript,function,scope,Javascript,Function,Scope,总结范围链接的概念: 一旦加载了网页,Javascript就会定位函数定义,并为每个函数定义创建一个所谓的变量对象。 每个VO必须引用每个局部变量(或全局变量),因此从第一个祖先的函数开始,直到全局上下文。 每个函数的作用域链存储在名为:scope的函数属性中 此外,当调用函数时,将创建一个新对象:激活对象 这是什么 它的行为就像一个变量对象(实际上是一个VO),负责引用所有函数内部的变量对象,包括“arguments”对象和形式参数 当然,由函数祖先的变量对象+函数的激活对象组成的链中的每一个

总结范围链接的概念:

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

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

这是什么

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

当然,由函数祖先的变量对象+函数的激活对象组成的链中的每一个都首先将所有变量映射到
未定义的
。然后,随着执行的进行,它通过更新其值(对应于引用的变量)来发展

然而,我注意到Activation对象与Variable对象不同,这仅仅是因为它包含参数对象,并且这一事实将阻止在调用函数之前创建它

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


它能提高性能吗?实际上,在每次调用时重新创建整个激活对象可能会消耗。。或者此方案存在问题?

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

认为它类似于为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()
的两个调用都共享一个
参数
实例,那么当我随后调用“counter1()”时会发生什么情况?

我相信在ECMAScript 5中没有“激活对象”。它现在被称为“可变环境”。此外,这可能有助于澄清一些问题。在像C这样的旧语言中,“激活记录”是在堆栈上分配的——换句话说,它是“堆栈框架”。在JavaScript中,当函数通过实例化一个函数并返回它(或将它绑定到某个全局对象)来公开一个闭包时,激活记录可以“存活”到函数调用结束后。是的,但这与我写的并不矛盾。我想知道为什么这些激活对象不是在函数定义步骤中单独创建的。@Mik378因为该对象表示函数的每个不同调用。每个调用都必须有自己的
参数
实例等。这就是我说的:)“引擎只会清除相应的参数对象”。例如,test(color)函数在调用执行时创建了自己的激活对象。我的问题是:为什么不在函数定义步骤创建它,并在每次调用同一个函数时刷新它(清除类似数组的arguments对象),而不是每次重建所有局部变量映射。因为无论如何,内部局部变量都会被分配给未定义的变量,直到执行进行并更新它们。arguments对象表示参数,这些参数是调用上下文的一部分。如果函数调用返回一个函数,而该函数又引用了原始函数中的一个参数,该怎么办?如果arguments实例后来被清除,则闭包将被损坏。@Mik378请参阅对答案的编辑。注意,由于
参数
的工作方式很奇怪,伪数组的元素实际上是参数的别名。