Javascript 是否为每个嵌套函数创建单独的闭包实例?

Javascript 是否为每个嵌套函数创建单独的闭包实例?,javascript,Javascript,抱歉,如果我的术语有点不正确。。。当一个函数包装另一个函数并创建闭包时,是否每次调用外部函数时都会创建一个新的闭包实例(“内存中的空间”) 根据我这里的代码,我相信答案是肯定的: (function(){ var ob = {}, names=['one', 'two'], i=0; var outer = function(val){ ob[names[i++]] = function(){ return val; }; }; outer(3

抱歉,如果我的术语有点不正确。。。当一个函数包装另一个函数并创建闭包时,是否每次调用外部函数时都会创建一个新的闭包实例(“内存中的空间”)

根据我这里的代码,我相信答案是肯定的:

(function(){
  var ob = {}, names=['one', 'two'], i=0;

  var outer = function(val){

    ob[names[i++]] = function(){
      return val;
    };

  };

  outer(3);
  outer(999);

  console.log(ob.one());
  console.log(ob.two());
})();
考虑到结果是

3
999
而不是

999
999
似乎
ob.one
指向
ob.two
的不同闭包实例-每个实例都有自己的
val

是不是不仅仅是我的术语让人困惑

是否为每个嵌套函数创建单独的闭包实例

是的,这是一个理想的特性

一个更理想的特性是块级别的作用域,这是javascript所没有的。事实上,为了在javascript中对-循环执行嵌套的
,有必要滥用嵌套函数,否则变量绑定将在背后发生变异(例如,如果您将其交给回调,您可以自己演示;想象一下您正在定义的函数是,例如,不同元素的onClick处理程序;您将希望绑定不同)


当然,如果您不喜欢此功能,您可以始终使用您在外部范围中定义的变量,例如您也可以使用。=)

如果将
ob
调用为
internal
,则会更好,但无论如何

…是否每次调用外部函数时都会创建一个新的闭包实例(“内存中的空间”?)

是和否。分配给外部匿名函数的函数具有外部匿名函数的激活/变量对象的闭包。调用outer时,该对象被放置在其作用域链上,并用于标识符解析。每次都是同一个对象(ECMA-262没有说明如何实现,但出于所有目的,它都是同一个对象)

分配给
ob[names[i++]
的函数对调用并分配该函数时创建的激活/变量对象实例有一个闭包。因此,每次调用outer时,都会创建一个新的激活/变量对象,并且每个ob[…]函数都有一个到不同的外部激活/变量对象的闭包,但是相同的匿名函数激活/变量对象

我希望这是有道理的

考虑到结果是

3
999
3999

而不是

999
999
999 999

似乎ob.one指向一个 ob.two的不同闭包实例 -每个都有自己的val值

这两个函数在其作用域链上具有相同的匿名函数激活/变量对象,因此“共享”obj、names和i的闭包。但每个都是其作用域链上外部激活/变量对象的唯一实例,因此val将解析为相同的属性名称,但在不同的对象上(即,它们不共享相同的val属性)

也许下面的范围链图是有意义的:

ob.one -> outerA -> anonymous fn -> global
ob.two -> outerB -> anonymous fn -> global
所以ob.one和ob.two在其作用域链上有一个外部实例,但它们是不同的实例。它们的作用域链上具有相同的匿名函数和全局对象