時間設(shè)置為0時并不會立即執(zhí)行
正確理解setTimeout的方式(注冊事件):
1荔泳、有兩個參數(shù)橙数,第一個參數(shù)是函數(shù)尊流,第二參數(shù)是時間值。
2灯帮、調(diào)用setTimeout時崖技,把函數(shù)參數(shù),放到事件隊列中钟哥。等主程序運行完迎献,再調(diào)用。
for (var i = 0; i < 3; i++) {
setTimeout(function() {
console.log(i);
}, 0);
console.log(i);
}
結(jié)果是:0 1 2 3 3 3
setTimeout(function() {
console.log(1);
}, 0);
console.log(2);
先打印2腻贰,后打印1吁恍。
事件設(shè)置不為0時,可能并不會按時執(zhí)行
setTimeout(fn, 2000)
我們可以理解為2000之后播演,再放入事件隊列中冀瓦,如果此時隊列為空,那么就直接調(diào)用fn写烤。如果前面還有其他的事件翼闽,那就等待。
因此setTimeout是一個約會從來都不準(zhǔn)時的童鞋洲炊。
巧妙利用這個機(jī)制
我們進(jìn)行dom操作可以先綁定事件感局,然后再去寫其他邏輯尼啡。
setTimeout(function() {
console.log(i);
}, 0);
var i = 1;
// 1
因為先執(zhí)行vari=1,所以并不會報錯
window.onload = function() {
fn();
}
var fn = function() {
alert('hello')
};
這個是一個項目的運用询微,dom加載完成后崖瞭,再獲取節(jié)點,setTimeout是一個宏任務(wù)撑毛,它在事件隊列里排在了script標(biāo)簽這個宏任務(wù)的后面
aaaaa.png
定時器與塊級作用域
但此問題在es6里終結(jié)了读恃,因為es6,發(fā)明了let代态。
for (var i = 0; i < 3; i++) {}
console.log(i);
es5中是沒有塊級作用域的,i可以在for循環(huán)體外訪問到
有關(guān)的面試題目
var i = 0;
setTimeout(function() {
console.log(i);
}, 0);
console.log(i);
i++;
setTimeout(function() {
console.log(i);
}, 0);
console.log(i);
i++;
setTimeout(function() {
console.log(i);
}, 0);
console.log(i);
i++;
根據(jù)前面的理解疹吃,可以把題目轉(zhuǎn)換為
var i = 0;
console.log(i);
i++;
console.log(i);
i++;
console.log(i);
i++;
setTimeout(function() {
console.log(i);
}, 0);
setTimeout(function() {
console.log(i);
}, 0);
setTimeout(function() {
console.log(i);
}, 0);
結(jié)果是0 1 2 3 3 3
定時器與閉包
var fn = function() {
for (var i = 0; i < 3; i++) {
setTimeout(function() {
console.log(i);
}, 0);
console.log(i);
}
};
fn();
上面的函數(shù)跟我們常見另一個例子(div綁定事件)有什么區(qū)別:
var fn = function() {
var divs = document.querySelectorAll('div');
for (var i = 0; i < 3; i++) {
divs[i].onclick = function() {
alert(i);
};
}
};
fn();
點擊每個div都會彈出3蹦疑。道理是一樣的。因為alert(i)中的i是fn作用越中的萨驶,因而這是閉包歉摧。
怎么保證能彈出0,1腔呜, 2呢叁温。解決之道:再創(chuàng)建個閉包!核畴!
var fn = function() {
var divs = document.querySelectorAll('div');
for (var i = 0; i < 3; i++) {
divs[i].onclick = (function(i) {
return function() {
alert(i);
};
})(i);
}
};
fn();
或者如下的寫法:
var fn = function() {
var divs = document.querySelectorAll('div');
for (var i = 0; i < 3; i++) {
(function(i) {
divs[i].onclick = function() {
alert(i);
};
})(i);
}
};
fn();
因此原題如果也想setTimeout也彈出0膝但,1,2的話谤草,改成如下:
for (var i = 0; i < 3; i++) {
setTimeout((function(i) {
return function() {
console.log(i);
};
})(i), 0);
console.log(i);
}
本文章只作為自己的學(xué)習(xí)筆記跟束,如有侵權(quán)行為請聯(lián)系我