JavaScript:如何给setTimeout传递参数

本文介绍一种在使用异步函数setTimeout时给其带上参数的方法。

写这篇文章的时候,在高级浏览器比如Google Chrome上,setTimeout已经支持带第二个以外的参数,而且IE10 、IE11也是可以的,效果如下所示:

IE9以及以下,还不支持:

针对这种情况,其实也有解决办法的,思路就是重写setTimeout方法。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>settimeout</title>
</head>
<body>
    <div id="root">

    </div>

    <script type="text/javascript">
        function add(a,b){
            return a + b;
        }
        var __sto = setTimeout;
      window.setTimeout = function(callback,timeout,param){
          var args = Array.prototype.slice.call(arguments,2);
          var _cb = function(){
              callback.apply(null,args);
          }
          __sto(_cb,timeout);
      }
        window.onload = function(){
            window.setTimeout(function(a,b){
                console.log("a + b = ",add(a,b))
            },1000,3,5);
        }
    </script>
</body>
</html>

     上面这段在HTML文件中的<script></script>部分重新定义setTimeout的做法就可以解决ie9以及以下版本中传参数的问题。运行效果如下所示:

    

    如果去掉重写setTimeout的部分,结果如下所示:

    

    这段代码的核心就在这里:  

var __sto = setTimeout;
window.setTimeout = function(callback,timeout,param){
  var args = Array.prototype.slice.call(arguments,2);
  var _cb = function(){
      callback.apply(null,args);
  }
  __sto(_cb,timeout);
}

    重写的时候,给原来的函数取个别名,虽然用不了第二个以外的参数,但是它还是可以传进来的,我们就把它取出来,传递到回调函数中,再调用回调函数,这样就解决了传参问题。

    这种办法虽然是一种兼容的办法,但是它破坏了其他浏览器原生setTimeout的方法,看似很好,其实也有一点不好。

    其实对于IE浏览器的版本问题,我们还有一种使用IE条件注释判断表达式判断浏览器版本的办法,将重写代码放入HTML中,只有IE浏览器才能识别并起作用。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>settimeout</title>
</head>
<body>
    <div id="root">

    </div>
    <!--[if lte IE 9]>
        <script>
            (function(f){
                window.setTimeout=f(window.setTimeout);
                window.setInterval=f(window.setInterval);
            })(function(f){
                return function(c,t){
                    var a=[].slice.call(arguments,2);
                    return f(function(){
                        c instanceof Function?
                        c.apply(this,a):eval(c)
                    },t)
                }
            });
        </script>
    <![endif]-->
    <script type="text/javascript">
        function add(a,b){
            return a + b;
        }
        window.onload = function(){
            setTimeout(function(a,b){
                console.log("a + b = ",add(a,b))
            },1000,3,5);
        }
    </script>
</body>
</html>

     这种办法的好处就是对于IE内核之外的浏览器,它可以直接使用native的setTimeout。缺点就是他嵌入了HTML中,不能与HTML分离,在大型项目中,需要放在一个全局的HTML页面中,才能不至于哪哪都要加这段代码。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章