setTimeout
語法:
var timeoutId = scope.setTimeout(function[, delay, param1, param2....]);
var timeoutId = scope.setTimeout(function[, delay]);
var timeoutId = scope.setTimeout(code[, delay]);
複製程式碼
setTimeout
要點一:
setTimeout第一個引數可以是一個函式,也可以是一個包含Javascript程式碼的字串(可以類比eval()
中使用字串)
//方式1:一般的書寫方式
setTimeout(function(){
console.log(a)
},1000)
//方式2:也可以使用字串
setTimeout("console.log(a)",1000);
複製程式碼
不過,不推薦方式2,不論是程式碼可讀性,還是MDN的官方解釋-安全原因,亦或是在舊版瀏覽器中的效能原因~~。
setTimeout
要點二:
Javascript是一個單執行緒的直譯器,因此一段時間只能執行一段程式碼,所以會有Javascript任務佇列,這些任務會按照它們佇列的順序執行。而setTimeout的第二個引數-delay
告訴Javascript再過多久把當前任務新增到佇列中。
如果省略該引數,delay
取預設值0。實際的延遲時間可能會比 delay 值長【通常是由於函式巢狀導致(巢狀層級達到一定深度),或者是由於已經執行的setInterval的回撥函式阻塞導致】。
根據HTML5 spec 中精確的數值,delay
延遲時間大於等於4ms,即便你把delay
設為0
setTimeout
要點三:
setTimeout可選引數:附加引數,一旦定時器執行,它們會作為引數傳遞給function 或 執行字串(setTimeout引數中的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
});
複製程式碼
setTimeout
要點四:
setTimeout都是在全域性作用域下執行的,因此函式中的this都是指向window物件(一般情況下,排除使用ES6中的箭頭函式、Function.prototype.bind()、閉包重寫作用鏈物件。。。。等等更改作用域的其他方式)
var obj = {
timer:function(){
setTimeout(function(){
console.log(this == window) //true
})
}
}
obj.timer()
複製程式碼
雖然有不少的書上/文件中寫著,嚴格模式下,this是undefined.
BUT,在嚴格模式下,setTimeout( )的回撥函式裡面的this仍然預設指向window物件, 並不是undefined
"use strict";
setTimeout(function(){
console.log(this == window) //true
})
複製程式碼