最近在學習的時候發(fā)現(xiàn)setTimeout/setInterval居然有第三個參數(shù),以前我們在使用setTimeout/setInterval的時候我們一般都只是傳一個回調(diào)函數(shù)再加上一個時間延遲。
我們先來看看MDN上是怎么解釋的吧
語法
var timeoutID = scope.setTimeout(function[, delay, param1, param2, ...]);
var timeoutID = scope.setTimeout(function[, delay]);
var timeoutID = scope.setTimeout(code[, delay]);
參數(shù)中帶 [ ] 的表示可傳可不傳
param1, param2, ... 附加參數(shù),一旦定時器到期,它們會作為參數(shù)傳遞給 function 或 執(zhí)行字符串(setTimeout參數(shù)中的code)
可以當作參數(shù)傳給回調(diào)函數(shù),上代碼玩玩:
function foo(x,y){
console.log(x,y)
}
setTimeout(foo,2000,1,2) // 輸出1 2
闊以,不過要注意的一點就是兼容問題,MDN上面也提出了,它的描述:
如果你需要向你的回調(diào)函數(shù)內(nèi)傳遞一個參數(shù), 而且還需要兼容IE9及以前的版本, 由于IE不支持傳遞額外的參數(shù) (setTimeout() 或者 setInterval()都不可以) ,但你可以引入下面的兼容代碼.該代碼能讓IE也支持符合HTML5標準的定時器函數(shù).
兼容舊IE代碼太多,我就不在這貼了,想了解的可以去這里看看MDN兼容舊IE代碼
那么我們了解了有這個特性后,我們可以干點啥嘞?
相信很多小伙伴去面試的時候都會遇到這么一個問題:
請問這個會輸出什么
function foo(){
for (var i=0; i <=5; i++) {
setTimeout(function(){
console.log(i)
},0)
};
}
foo();
當然是666666!至于為什么,這就涉及到了作用域以及setTimeou的異步性了--解答,注意作者最后第四
條說因為setTimeout 不支持傳帶參數(shù)的函數(shù),其實是因為他在第一個參數(shù)傳了一個函數(shù)調(diào)用,而人家第一個參數(shù)
是需要一個函數(shù),這里他的解答有誤
那么解決方法我們一般這樣做:
function foo(){
for (var i=0; i <=5; i++) {
(function(x){
setTimeout(function(){
console.log(x)
},0)
}(i))
};
}
foo(); // 0 1 2 3 4 5
利用閉包保存i值的方式傳參,但是這樣看起來很雜,我想接下來的解決方法,大家肯定都知道了,利用定時器的第三個參數(shù)來傳參
function foo(){
for (var i=0; i <=5; i++) {
setTimeout(function(x){
console.log(x)
},0,i)
};
}
foo(); // 0 1 2 3 4 5
這樣是不是就爽快多了