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在其作用域链上有一个外部实例,但它们是不同的实例。它们的作用域链上具有相同的匿名函数和全局对象