关于闭包问题

hztgcl1986 2011-12-02 10:15:15
代码段1

function f(x)
{
var g = function () { return x; }
return g;
}

var g1 = f(1);
var g2 = f(2);
alert(g1()); //输出 1
alert(g2()); //输出 2


代码段2

function a()
{
var array = new Array();
for (var i = 0; i < 10; i++)
{
array.push(function() {return i});
}

return array;
}

var array = a();
for (var i = 0; i < array.length; i++)
{
window.alert(array[i]()); //全是10
}


同样都是闭包,为什么第1段代码输出的值不同,而第二段相同呢?

...全文
217 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
JParser 2012-03-31
  • 打赏
  • 举报
回复
修正:

...10个function 都是在a一次执行中定义完成的。
JParser 2012-03-31
  • 打赏
  • 举报
回复
没错,你的两个都有闭包。
为什么不一样,
第二个里面,你在a里定义了10 个function,注意这个10 个function 都是在a执行时,一定定义完成的。function 在定义的解析的时候,会有一个[[scope]]属性指向它定义时所在的环境,这10个function 都指向了这一个a执行时的环境,而i就是在这个环境中的一个变量。随着执行的完成,i最后变成了10。当你在外面再通过数组项的function 引用去调这些function 时,这些function 对这个i的解析是同一个,所以会是10。

而第一个,

你是通过两次执行同一个function,返回两个function 的引用。function 每次执行都没生成不一样的运行环境,返回的这两个function 的[[scope]]的指向也是不一样的,分别两个不同的变量,只是表面名字一样,所以结果也不一样了。
HPhone 2012-03-31
  • 打赏
  • 举报
回复
函数链保存着呢,返回i的结果,这个i和后面的函数i的地址是同一个,后来改变了,自然变化了



function a()
{
var array = new Array();
for (var i = 0; i < 10; i++)
{
var j=i;
array.push(function() {return j});
}

return array;
}

var array = a();
for (var i = 0; i < array.length; i++)
{
window.alert(array[i]());
}
hztgcl1986 2011-12-02
  • 打赏
  • 举报
回复
还有,为什么代码1中输出结果不一样呢? g1和g2中的闭包包含的都是f的作用域啊?
hookee 2011-12-02
  • 打赏
  • 举报
回复
array.push(function() {return i}); 此时 i 并没有固定到 匿名函数中,等到匿名函数运行时还是用的scope a中的i
hztgcl1986 2011-12-02
  • 打赏
  • 举报
回复
很明显,我的代码2是闭包,但是为什么都输出10,我认为3楼是正确的
逍遥庄主 2011-12-02
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 babyboy9685 的回复:]

1 楼正确 但 好像返回的不是楼主想要的那个东西 这样返回后 数组中只是一组数 了
[/Quote]

对不起 是我不细心 1楼是对的 我看错行了 Sorry
逍遥庄主 2011-12-02
  • 打赏
  • 举报
回复
1 楼正确 但 好像返回的不是楼主想要的那个东西 这样返回后 数组中只是一组数 了
licip 2011-12-02
  • 打赏
  • 举报
回复
1楼正确
逍遥庄主 2011-12-02
  • 打赏
  • 举报
回复
这是闭包么?这只是你前边定义一个函数 在后边去调用的他啊

把你这代码打上断点 调试跟踪一下你就能看到 了 是从 var array = a(); 执行时 才会去调你写的方法

把下边的循环 换个变量 j 你就能看出 其实你这个Array里放的 都 是 function(){return i} 这个i 在前边那个循环结束后 就是10了 第二个循环 你再调 用时 返回的i 不就是10么
暗夜螃蟹 2011-12-02
  • 打赏
  • 举报
回复

array.length 打出来看看不就知道是什么原因了吗

liangws 2011-12-02
  • 打赏
  • 举报
回复
1楼是对的
楼主
for (var i = 0; i < 10; i++)
{
array.push(function() {return i});
}

这样做。function() {return i}的时候i是在a的变量作用域中

hztgcl1986 2011-12-02
  • 打赏
  • 举报
回复
代码2按我的写法,已经形成了闭包了啊
MuBeiBei 2011-12-02
  • 打赏
  • 举报
回复
<script>
function a()
{
var array = new Array();
for (var i = 0; i < 10; i++)
{(function(i){
array.push(function() {return i});
})(i)}

return array;
}

var array = a();
for (var i = 0; i < array.length; i++)
{
window.alert(array[i]()); //全是10
}
</script>


代码2应该这么写~·才会形成闭包~·
oggmm 2011-12-02
  • 打赏
  • 举报
回复
代码1的x是通过传参进来的,是随着所传的参数而变化的;代码2的a()里面的i和array是在同一个作用域,其实你在返回array的时候数组元素里面i的值都是一样,那么返回数组时最后变成什么值就都是什么值

87,917

社区成员

发帖
与我相关
我的任务
社区描述
Web 开发 JavaScript
社区管理员
  • JavaScript
  • 无·法
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧