关于 JavaScript 闭包的简朴例子

于掌握台中运转以下例子:

例 ①:无闭包

var x = [];
for (var i = 0; i < 9; i++) {
    setTimeout(function () {
        x[i] = i
    }, 1000)
}
console.log(i);
console.log(x);    // ▶(10) [empty × 9, 9]

例 ②:闭包

var y = [];
function doSetTimeout(i) {
    setTimeout(function () {
        y[i] = i;
    }, 1000);
}
for (var i = 0; i < 9; i++) {
    doSetTimeout(i);
}
console.log(i);
console.log(y);    // ▶(9) [0, 1, 2, 3, 4, 5, 6, 7, 8]

注重上述两个例子中,

  • 例 ① 中,x = [empty × 9, 9]length10
  • 例 ② 中,y = [0, 1, 2, 3, 4, 5, 6, 7, 8]length9

由于轮回体是 i++,轮回完毕 i = 9
我们把 setTimeout等待时间改成0,再看效果:

var y = [];
function doSetTimeout(i) {
    setTimeout(function () {
        y[i] = i;
    }, 0);
}
for (var i = 0; i < 9; i++) {
    doSetTimeout(i);
}
console.log(y);    // ▶(9) [0, 1, 2, 3, 4, 5, 6, 7, 8]

简写

var z = [];
for (var i = 0; i < 9; i++) {
    (function (i) {
        setTimeout(function () {
            z[i] = i;
        }, 1000)
    })(i);
}
console.log(z);

引伸

注重,假如我们将上面的例子改成:

var z = [];
for (var i = 0; i < 9; i++) {
    (function () {
        setTimeout(function () {
            z[i] = i;
        }, 1000)
    })();
}
console.log(z);    // ▶(10) [empty × 9, 9]

我们看输出效果是什么,注重函数体中的 i 是函数体内部专有的照样援用的全局变量?
然后,我们进一步修正上述代码,看看效果又会是不是到达预期:

var z = [];
for (var i = 0; i < 9; i++) {
    (function () {
        var j = i
        setTimeout(function () {
            z[j] = j;
        }, 1000)
    })();
}
console.log(z);
    原文作者:l1xnan
    原文地址: https://segmentfault.com/a/1190000006193111
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞