小tip之关于setTimeout的一点小发现

最近比较偶然的发现了一个setTimeout的非标准用法,也算是解决了我之前一直觉得不爽的一个问题。

概总

setTimeout的标准中支持两个参数,这个大家知道的,一直觉得有一个不太好的地方就是,setTimeout的第一个参数,如果我需要回调的函数,需要传入参数,那么就需要使用一个匿名函数处理了。

常用示例

如现在,我们如果需要回调一个带参数的回调函数,那么必须是如下的写法了:


function fn(a){
    alert("a="+a);
}

setTimeout(function(){
    fn("b");
},1000);


非标准setTimeout用法

最近发现的一个setTimeout的非标准用法,就是setTimeout可以支持多于两个的参数,并且从第三个参数开始,都是用来表示回调函数的传入的参数的,比如实现上述代码,的非标准setTimeout实现形式就可以如下:


function fn(a){
    alert("a="+a);
}

setTimeout(fn,1000,"b");


对于我个人来说,可以不添加匿名函数,是最让我感觉舒服的写法了。而这里就实现了这种~~~

既然说,是非标准的用法了,那么兼容性就肯定是不需要多说的了,IE9-(包括IE9)都是不支持这种写法的。

IE10+的浏览器支持,所以这种写法,其实是可以用于移动端开发的。

兼容性扩展

其实如果想要兼容IE9-的浏览器,那么我们常用的方法,就很简单的去进行一个扩展即可。

我觉得,这个地方最安全的扩展就是使用功能性验证的方法,但这个方法判断有一个缺点就是,在setTimeout扩展之前,不能使用该属性。


setTimeout(function(a){
    if(a !== "a"){
	//表示,不支持参数的传递,那么只能~~重写
	var _setTimeout = setTimeout;
	//先把原有的setTimeout方法,保存到_setTimeout中去
	//然后重写一个函数,覆盖原来的setTimeout方法,如下:
	setTimeout = function(){
	    var that = this,
		callBack = arguments[0],
		sec = arguments[1],
		arr = [].slice.call(arguments,2);
				
	    _setTimeout(function(){
		callBack.apply(that,arr);
	    },sec);
	}	
    }
    
    callback();
    //执行一次~~~
},0,"a");

function fn(a){
    alert("a="+a);
}

function callback(){
    setTimeout(fn,1000,"b");
    //用来验证上述写法的	
}


当然啦,如果你还要控制回调函数内部this的指向的话,那么还是好好的使用两个参数的写法吧。因为这个时候,如果还是要使用后面的快捷参数传入,就会变得复杂了。

比如callback的函数,就要如下的写法了:


function callback(){
    setTimeout(function(){
	fn.apply(this,arguments);
	//这个时候,如果要把第三个参数带过去
	//就得这么回调函数了,略显复杂了
    },1000,"b");
}


相对于原有的使用两个参数的写法:


function callback(){
    setTimeout(function(){
	fn.call(this,"b");
    },1000);
}


这使用两种参数的写法,更显得好些直接~~~

这只是一个非标准的使用方法,只是个人觉得很好玩,在之前也没有想象到过这个东西,所以,就有了这篇分享文章。

同时,setInterval也是具有相同的情况的,当然,如果想要在所有浏览器下都使用,那么按照上述setTimeout重写时,可以同时把setInterval重写掉。

总结

该方法,也许以后不会成为标准,但是既然当前最新版本的浏览器都已经支持,那么也是可以作为一个了解的,之所以觉得不会被定为标准,只是觉得当前如果要控制回调函数内部this的指向时,这种用法,就显得有些复杂了,所以,总的来说,只能说是有些新奇,但同时也有些鸡肋了。

本文地址:http://www.zhangyunling.com/?p=384

发表评论

电子邮件地址不会被公开。 必填项已用*标注

您可以使用这些HTML标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>