for(var i = 0; i < 10; i++) {
setTimeout(function() {
console.log(i);
}, 1000);
}
//輸出結果都爲10,由於for()循環過程當中每次傳值,匿名函數並無執行,至關於執行10次function(){console.log(i);},循環結束i變爲10,因此輸出所有爲10;
複製代碼
for(var i = 0; i < 10; i++) {
(function(i) {
setTimeout(function() {
console.log(i);
}, 1000);
})(i);
}
//外部匿名函數當即執行,把 i 做爲參數,賦值給內部的 i ,由於是當即執行,因此每次循環輸出不一樣值。
複製代碼
同步:因爲js單線程,同步任務都在主線程上排隊執行,前面任務沒執行完成,後面的任務會一直等待;閉包
異步:不進入主線程,進入任務隊列,等待主線程任務執行完成後開始執行。好比咱們學的異步操做setTimeout和setInterval,等待主線程任務執行完,在開始執行裏面的函數異步
特性:可實現函數外訪問函數內變量,外層變量能夠不被垃圾回收機制回收,即延伸變量的做用範圍函數
缺點: 引用外層變量不被回收,會相比其餘函數佔用更高內存,使用不當容易形成內存泄漏。ui
for (var i = 0; i < lis.length; i++) {
// 利用for循環建立了當即執行函數
// 當即執行函數也成爲小閉包由於當即執行函數裏面的任何一個函數均可以使用它的i這變量
(function(i) {
lis[i].onclick = function() {
console.log(i);
}
})(i);
}
複製代碼
for (var i = 0; i < lis.length; i++) {
function(i) {
lis[i].index = i;
lis[i].onclick = function() {
console.log(this.index);
}
}
}
複製代碼
for (let i = 0; i < lis.length; i++) {
function(i) {
lis[i].onclick = function() {
console.log(i)
}
}
}
複製代碼