javascript - 我的 javascript 作用域有什么问题?

标签 javascript scope closures

<分区>

以下每次都会提醒 2

function timer() {
    for (var i = 0; i < 3; ++i) {
        var j = i;
        setTimeout(function () {
            alert(j);
        }, 1000);
    }
}

timer();

不应该 var j = i;j 设置到 setTimeout 的单独范围内吗?

而如果我这样做:

function timer() {
    for (var i = 0; i < 3; ++i) {
        (function (j) {
            setTimeout(function () {
                alert(j);
            }, 1000);
        })(i);
    }
}

timer();

它会按应有的方式提醒 012

有什么我想念的吗?

最佳答案

Javascript 有函数作用域。这意味着

for(...) {
    var j = i;
}

相当于

var j;
for(...) {
    j = i;
}

事实上,这就是 Javascript 编译器实际处理这段代码的方式。而且,当然,这会导致您的小“技巧”​​失败,因为 j 将在 setTimeout 中的函数被调用之前递增,即 j 现在与 i 并没有真正做任何不同,它只是具有相同范围的别名。

如果 Javascript 有 block 作用域,你的技巧就会奏效,因为 j 将在每次迭代中成为一个新变量。

您需要做的是创建一个新范围:

for(var i = ...) {
    (function (j) {
        // you can safely use j here now
        setTimeout(...);
    })(i);
}

关于javascript - 我的 javascript 作用域有什么问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19914077/

相关文章:

c# - Winforms 中应用程序范围组件应该放在哪里?

JavaScript - 转换日期和时间(Chart.js 和 Moment.js)

javascript - 从 select 标签内的 ng-change 中的选项获取 $index

Javascript范围变量切换大小写?

javascript - 在 javascript 闭包中测试

javascript - 上传图片时如何传递参数?

sorting - 根据设置对具有多个闭包之一的向量进行排序

javascript - Python Beautiful Soup 抓取和解析

javascript - 单击鼠标更改(切换)html 按钮的图像(在 Internet Explorer 中)

javascript - 访问祖 parent 的变量