JavaScript不支持使用局部变量进行闭包吗?

JavaScript不支持使用局部变量进行闭包吗?

我对这段代码感到非常困惑:

var closures = [];function create() {
  for (var i = 0; i < 5; i++) {
    closures[i] = function() {
      alert("i = " + i);
    };
  }}function run() {
  for (var i = 0; i < 5; i++) {
    closures[i]();
  }}create();run();

根据我的理解,它应该打印0,1,2,3,4(这不是闭包的概念吗?)。

而是打印5,5,5,5,5。

我试过Rhino和Firefox。

有人可以向我解释这种行为吗?Thx提前。


GCT1015
浏览 366回答 3
3回答

翻过高山走不出你

通过添加额外的匿名函数修复了Jon的答案:function&nbsp;create()&nbsp;{ &nbsp;&nbsp;for&nbsp;(var&nbsp;i&nbsp;=&nbsp;0;&nbsp;i&nbsp;<&nbsp;5;&nbsp;i++)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;closures[i]&nbsp;=&nbsp;(function(tmp)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;function()&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;alert("i&nbsp;=&nbsp;"&nbsp;+&nbsp;tmp); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}; &nbsp;&nbsp;&nbsp;&nbsp;})(i); &nbsp;&nbsp;}}解释是JavaScript的作用域是函数级的,而不是块级的,并且创建闭包只意味着封闭的作用域被添加到封闭函数的词法环境中。循环终止后,函数级变量i具有值5,这就是内部函数“看到”的内容。作为旁注:你应该注意不必要的函数对象创建,特别是在循环中;&nbsp;这是低效的,如果涉及DOM对象,很容易创建循环引用,从而在Internet Explorer中引入内存泄漏。

白衣染霜花

我想这可能是你想要的:var&nbsp;closures&nbsp;=&nbsp;[];function&nbsp;createClosure(i)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;closures[i]&nbsp;=&nbsp;function()&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;alert("i&nbsp;=&nbsp;"&nbsp;+&nbsp;i); &nbsp;&nbsp;&nbsp;&nbsp;};}function&nbsp;create()&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;(var&nbsp;i&nbsp;=&nbsp;0;&nbsp;i&nbsp;<&nbsp;5;&nbsp;i++)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;createClosure(i); &nbsp;&nbsp;&nbsp;&nbsp;}}

守着一只汪

解决方案是让一个自动执行的lambda包装你的数组push。你也将i作为参数传递给那个lambda。自执行lambda中的i值将影响原始i的值,一切都将按预期工作:function&nbsp;create()&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;(var&nbsp;i&nbsp;=&nbsp;0;&nbsp;i&nbsp;<&nbsp;5;&nbsp;i++)&nbsp;(function(i)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;closures[i]&nbsp;=&nbsp;function()&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;alert("i&nbsp;=&nbsp;"&nbsp;+&nbsp;i); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}; &nbsp;&nbsp;&nbsp;&nbsp;})(i);}另一个解决方案是创建另一个闭包,它捕获i的正确值并将其分配给另一个在最终lambda中“被捕获”的变量:function&nbsp;create()&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;(var&nbsp;i&nbsp;=&nbsp;0;&nbsp;i&nbsp;<&nbsp;5;&nbsp;i++)&nbsp;(function()&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;x&nbsp;=&nbsp;i; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;closures.push(function()&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;alert("i&nbsp;=&nbsp;"&nbsp;+&nbsp;x); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}); &nbsp;&nbsp;&nbsp;&nbsp;})();}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript