为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

GCT1015 2019-07-30 14:58:24
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提前。
查看完整描述

3 回答

?
翻过高山走不出你

TA贡献1875条经验 获得超3个赞

通过添加额外的匿名函数修复了Jon的答案:

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

解释是JavaScript的作用域是函数级的,而不是块级的,并且创建闭包只意味着封闭的作用域被添加到封闭函数的词法环境中。

循环终止后,函数级变量i具有值5,这就是内部函数“看到”的内容。


作为旁注:你应该注意不必要的函数对象创建,特别是在循环中; 这是低效的,如果涉及DOM对象,很容易创建循环引用,从而在Internet Explorer中引入内存泄漏。


查看完整回答
反对 回复 2019-07-30
?
白衣染霜花

TA贡献1796条经验 获得超10个赞

我想这可能是你想要的:

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


查看完整回答
反对 回复 2019-07-30
?
守着一只汪

TA贡献1872条经验 获得超3个赞

解决方案是让一个自动执行的lambda包装你的数组push。你也将i作为参数传递给那个lambda。自执行lambda中的i值将影响原始i的值,一切都将按预期工作:

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

另一个解决方案是创建另一个闭包,它捕获i的正确值并将其分配给另一个在最终lambda中“被捕获”的变量:

function create() {
    for (var i = 0; i < 5; i++) (function() {
        var x = i;

        closures.push(function() {
            alert("i = " + x);
        });
    })();}


查看完整回答
反对 回复 2019-07-30
  • 3 回答
  • 0 关注
  • 365 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号