於控制檯中運行以下例子:閉包
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
,再看結果:code
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);
注意,若是咱們將上面的例子改成:io
var z = []; for (var i = 0; i < 9; i++) { (function () { setTimeout(function () { z[i] = i; }, 1000) })(); } console.log(z); // ▶(10) [empty × 9, 9]
咱們看輸出結果是什麼,注意函數體中的 i
是函數體內部專有的仍是引用的全局變量?
而後,咱們進一步修改上述代碼,看看結果又會是否達到預期:console
var z = []; for (var i = 0; i < 9; i++) { (function () { var j = i setTimeout(function () { z[j] = j; }, 1000) })(); } console.log(z);