for( i=0; i<3; i++){
? setTimeout(function(){
console.log(i)
? ? },10)
? console.log(i)
}
打印結(jié)果是:0 1 2 3 3 3
很多公司面試都愛出這道題冒窍,此題考察了異步、作用域畜挨、閉包知識(shí)點(diǎn)贰盗。
setTimeout是異步的许饿,正確的理解setTimeout的方式(注冊(cè)事件): 有兩個(gè)參數(shù),第一個(gè)參數(shù)是函數(shù)舵盈,第二參數(shù)是時(shí)間值陋率。 調(diào)用setTimeout時(shí),把函數(shù)參數(shù)秽晚,放到事件隊(duì)列中瓦糟,等主程序運(yùn)行完,再調(diào)用赴蝇。
要點(diǎn)一:
var timeoutId = scope.setTimeout(function[, delay, param1, param2....]);
var timeoutId = scope.setTimeout(function[, delay]);
var timeoutId = scope.setTimeout(code[, delay]);
setTimeout第一個(gè)參數(shù)可以是一個(gè)函數(shù)菩浙,也可以是一個(gè)包含Javascript代碼的字符串(可以類比eval()中使用字符串)
setTimeout第一個(gè)參數(shù)可以是一個(gè)函數(shù),也可以是一個(gè)包含Javascript代碼的字符串(可以類比eval()中使用字符串)
//方式1:一般的書寫方式
setTimeout(function(){
console.log(a)
},1000)
//方式2:也可以使用字符串
setTimeout("console.log(a)",1000);
不過(guò)句伶,不推薦方式2劲蜻,不論是代碼可讀性,還是MDN的官方解釋-安全原因考余,亦或是在舊版瀏覽器中的性能原因~~先嬉。
要點(diǎn)二:
Javascript是一個(gè)單線程的解釋器,因此一段時(shí)間只能執(zhí)行一段代碼楚堤,所以會(huì)有Javascript任務(wù)隊(duì)列疫蔓,這些任務(wù)會(huì)按照它們隊(duì)列的順序執(zhí)行。而setTimeout的第二個(gè)參數(shù)-delay告訴Javascript再過(guò)多久把當(dāng)前任務(wù)添加到隊(duì)列中身冬。
如果省略該參數(shù)衅胀,delay取默認(rèn)值0。實(shí)際的延遲時(shí)間可能會(huì)比 delay 值長(zhǎng)【通常是由于函數(shù)嵌套導(dǎo)致(嵌套層級(jí)達(dá)到一定深度)吏恭,或者是由于已經(jīng)執(zhí)行的setInterval的回調(diào)函數(shù)阻塞導(dǎo)致】拗小。
根據(jù)HTML5 spec 中精確的數(shù)值,delay延遲時(shí)間大于等于4ms樱哼,即便你把delay設(shè)為0
要點(diǎn)三:
setTimeout可選參數(shù):附加參數(shù)哀九,一旦定時(shí)器執(zhí)行剿配,它們會(huì)作為參數(shù)傳遞給function 或 執(zhí)行字符串(setTimeout參數(shù)中的code)。
setTimeout(function(param1,param2){
console.log(param1)? //a
console.log(param2)? //b
},1000,'a','b')
function timeout(ms) {
return new Promise((resolve, reject) => {
setTimeout(resolve, ms, 'finish');
});
}
timeout(100).then((value) => {
console.log(value); //finish
});
要點(diǎn)四:
setTimeout都是在全局作用域下執(zhí)行的阅束,因此函數(shù)中的this都是指向window對(duì)象(一般情況下呼胚,排除使用ES6中的箭頭函數(shù)、Function.prototype.bind()息裸、閉包重寫作用鏈對(duì)象蝇更。。呼盆。年扩。等等更改作用域的其他方式)
var obj = {
timer:function(){
setTimeout(function(){
console.log(this == window)? ? //true
})
}
}
obj.timer()
雖然有不少的書上/文檔中寫著,嚴(yán)格模式下访圃,this是undefined.
BUT厨幻,在嚴(yán)格模式下,setTimeout( )的回調(diào)函數(shù)里面的this仍然默認(rèn)指向window對(duì)象腿时, 并不是undefined
"use strict";
setTimeout(function(){
console.log(this == window)? ? //true
})
參考:https://blog.csdn.net/qq_35087256/article/details/80489891