`
zha_zi
  • 浏览: 584077 次
  • 性别: Icon_minigender_1
  • 来自: 西安
社区版块
存档分类
最新评论

setinterval 使用闭包解决参数不能传递的问题

阅读更多

settimeout、setinterval执行能传递参数的函数(闭包)

无论是window.setTimeout还是window.setInterval,在使用函数名作为调用句柄时都不能带参数,而在许多场合必须要带参数,这就需要想方法解决。经网上查询后整理如下:

例如对于函数hello(_name),它用于针对用户名显示欢

迎信息:

var userName="jack";
//根据用户名显示欢迎信息
function hello(_name){
      alert("hello,"+_name);
}

 
这时,如果企图使用以下语句来使hello函数延迟3秒执行是不可行的:
window.setTimeout(hello(userName),3000);
这将使hello函数立即执行,并将返回值作为调用句柄传递给setTimeout函数,其结果并不是程序需要的。而使用字符串形式可以达到想要的结果:
window.setTimeout("hello(userName)",3000);这是方法(一)

这里的字符串是一段JavaScript代码,其中的userName表示的是变量。但这种写法不够直观,而且有些场合必须使用函数名,于是有人想到了如下

方法(二):

<script language="JavaScript" type="text/javascript">
<!--
var userName="jack";
//根据用户名显示欢迎信息
function hello(_name){
    alert("hello,"+_name);
}
//创建一个函数,用于返回一个无参数函数
function _hello(_name){
    returnfunction(){
        hello(_name);
    }
}
window.setTimeout(_hello(userName),3000);
//-->
</script>

 
这 里定义了一个函数_hello,用于接收一个参数,并返回一个不带参数的函数,在这个函数内部使用了外部函数的参数,从而对其调用,不需要使用参数。在 window.setTimeout函数中,使用_hello(userName)来返回一个不带参数的函数句柄,从而实现了参数传递的功能。

另外也有人通过修改settimeout、setInterval来实现。即下面的

方法三:

<script language="JavaScript" type="text/javascript">
<!--
var userName="jack";
//根据用户名显示欢迎信息
function hello(_name){
    alert("hello,"+_name);
}//*=============================================================
//*   功能: 修改 window.setInterval ,使之可以传递参数和对象参数    
//*   方法: setInterval (回调函数,时间,参数1,,参数n)  参数可为对象:如数组等
//*============================================================= 
var __sto = setInterval;     
window.setInterval = function(callback,timeout,param){     
    var args = Array.prototype.slice.call(arguments,2);     
    var _cb = function(){     
        callback.apply(null,args);     
    }     
__sto(_cb,timeout);     
}
window.setInterval(hello,3000,userName);

 

//-->

 

 

 

 

//-------------------------------------------实例二----------------

<body>
<div id="time1">time1</div>
<div id="time2">time2</div>
</body>

<script>

function TimerC(id){
this.id=id;
this.count=0;
this.timer=null;
}
TimerC.prototype.begin=function(count){
this.count=count;
this.show(this)();
this.timer=setInterval(this.show(this),1000);
}
//在这里,当把this传进来以后,传给obj,obj是外部函数的变量,return function是内部函数,
//内部函数可以调用外部函数的变量obj,而且在外部函数已经执行完了后还可调用,所以obj一直有效.
//setInterval(下一秒)执行的函数是这个内部函数,不带参数的.而不是外部函数.不用闭包,只直行一次.
//如果直接把闭包函数写在setInterval里也行,这里可以判断后clearInterval.return function后等于使用此函数了。

 

TimerC.prototype.show=function(obj){
return function(){
if(obj.count<0){
document.getElementById(obj.id).innerHTML="over";
clearInteval(obj.timer);
return;
}
document.getElementById(obj.id).innerHTML=obj.count;
obj.count--;
}
}
var t2 = new TimerC("time2");
t2.begin(10);
</script>

 

 

 

//----------------------------实例三---------------------------

  1. function f(){   
        var a = [];   
        var i;   
        for(i=0;i<3;i++){   
            a[i] = function(){   
                alert(i);   
                return i;   
            }   
        }   
        return a;   
    }   
      
    var a= f();   
    a[0]();//3   
    a[1]();//3   
    a[2]();//3  
     
  2. //我们新建了三个闭包,都指向了变量i。闭包并没有记住变量i的值,它仅是变量i的引用。在循环结束后,i的值是3,所以结果都是3
  3. a[0]是个函数引用,所以后面要加()来执行。
  4. 也可以写成:
  5. a[i] = (function(x){    
  6.             alert(x);   
  7.             return x;   
  8.         })(这里传参数 i 给x)      
  9. 这样最后的a[0]就不用()了,因为a[i]付的值是return i;

 

 

function f() {   
  var a = [];   
  var i;   
  for(i = 0; i < 3; i++) {   
    a[i] = (function(x){   
      return function(){   
        alert(x);   
        return x;   
      }   
    })(i);   
  }   
  return a;   
}   
  
var a = f();   
a[0]();//0   
a[1]();//1   
a[2]();//2  

 

  1. //我们又用了一个闭包,把变量i变成了局部变量x了,x变量每次都是不同的值了。如果没有彻底理解自调用函数那就如下写法就可以明白了

 

function f() {   
var a = [];   
var i;   
for(i = 0; i < 3; i++) {   
a[i] = (function(x){   
//return function(){   
alert(x);   
return x;   
// }   
})(i);   
}   
return a;   
}   

var a = f();   
//a[0]();//0   
//a[1]();//1   
//a[2]();//2  
 
 
    <script type="text/javascript">
    
        function refreshImgTimeout(){
            return function(){
                setInterval(refreshImgInteval,2000);
            }
        }

        var refreshImgInteval=function(){
            var src="spectrum!spectrumImage.action?" + Math.random();
            $("#spectrumImg").attr("src",src);
        }

        $(function(){
            setTimeout(refreshImgTimeout(),2000);
        });
        
    </script>

 

这里不用a[0]();a[1]();a[2]();alert(x)在循环时执行.如果alert(a[0])//0,alert(a[0]())报错,提示a[0]不是函数

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics