你不知道的setTimeout第三个参数

你不知道的setTimout第三个参数

  提及setTimeout,各位再熟悉不过,用法也很简单:setTimeout(fun, delay)。html

  但提及来你可能不信,用了这么多年的setTimeout竟然有第三个参数下面一块儿看看这个setTimeout第三个参数。面试

  咱们先来看一段简单的代码:闭包

setTimeout(function(x) {
    console.log(x);
}, 1000, 1);

  控制台输出1,那么能不能继续加参数呢?咱们继续来看下面这段代码:异步

setTimeout(function(x,y) {
    console.log(x+y);
}, 1000, 1, 2);

  控制台输出的是3,很显然是第三和第四个参数的和。函数

  看到这里不少小伙伴应该意识到了,是的,setTimeout的第三个参数做用就是给setTimeout第一个函数的参数。post

  经过查询MDN(点击此传送门),咱们能看到关于第三个参数的描述:this

var timeoutID = scope.setTimeout(function[, delay, arg1, arg2, ...]);
var timeoutID = scope.setTimeout(function[, delay]);
var timeoutID = scope.setTimeout(code[, delay]);

  因此,其实准确来说,setTimeout能够有无数个参数,只是从第三个参数起,就是可选参数了。spa

  好了,知道这个特性后咱们能够解决什么问题呢?最经典的一个就是for循环内使用setTimeout了。code

for(var i = 0; i<6; i++) {

    setTimeout(function() {

        console.log(i);

    }, 1000);

}

  上面的这个例子是一个经典的面试题,它会连续输出6次6,由于setTimeout是一个异步操做,而等到执行setTimeout时,for循环已经执行完毕,这时的i已经等于6,因此输出6次的6。关于解决方法我总结了好几种,感兴趣的小伙伴能够看个人上一篇博客《关于for循环中使用setTimeout》,在这篇博客结尾我提到了使用setTimeout第三个参数,那咱们再来看看这种方法。htm

for(var i=0;i<6;i++) {

    setTimeout(function(j) {

        console.log(j);

    }, 1000, i);

}

  因为每次传入的参数是从for循环里面取到的值,因此会依次输出0~5。这固然仍是做用域的问题,可是在这里setTimeout第三个参数却把i的值给保存了下来。这种解决方法比使用闭包轻快的多。

  另外,第三个参数也能够做为函数来使用。

for(var i=0;i<6;i++) {

    setTimeout(function(j) {

        console.log(j);

    }, 1000, i);

}

  最后依次输出为第一次0第二次1

  能够看到第三个参数还能够是先执行,而后再执行函数。

  最后,使用第三个参数须要注意的一点就是兼容问题,若是须要兼容IE9及之前的版本,须要引入一段MDN提供的兼容旧IE代码 ,这里贴出传送门,感兴趣的能够去看。

  下面是MDN上关于兼容性的描述:

Note: Passing additional arguments to the function in the first syntax does not work in Internet Explorer 9 and below. If you want to enable this functionality on that browser, you must use a polyfill (see the Polyfill section).
相关文章
相关标签/搜索