于掌握台中运转以下例子:
例 ①:无闭包
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]
,length
为10
; - 例 ② 中,
y = [0, 1, 2, 3, 4, 5, 6, 7, 8]
,length
为9
。
由于轮回体是 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);