昨晚看《JavaScript核心技术》的BOM一章,上面写到setTimeout除了我们知道的两个参数(执行的函数,延迟时间)外后面还可以传一些参数,这些参数就是传递给“执行函数”的参数。
如 setTimeout(function add1(x,y){alert(x+y)},2000,3,5)会在2秒后弹出8,也许现在都明白这些参数的含义了。
近日突然想起于是测了一下,却失望的发现在IE下会弹出NaN,然后在add1里弹出arguments.length返回0,可见并没有将后面的两个参数传入add1中,不过在FF下确实是可以传入到add1中,看来又是一个IE/FF不兼容的特性,如此的一个特性其实挺好的,不晓得IE为何就不支持呢?每次都要在外面套一层Function真是麻烦。
接着在FF下测试setTimeout(function add1(){alert(arugments.length)},2000);执行后居然返回1,明明没有传参的,接着执行setTimeout(function add1(){alert(arugments.length)},2000,3);返回2,这不是多出了一个参数吗?
然后alert了最后的参数,发现延迟不同每次返回结果也都不同,而且都是数字。难道是setTimeout函数本身的执行时间?恩,应该是这样的,setTimeout本身执行也会有时间开销的。
作如下测试:
function add(){
alert((new Date().getTime()-t)+","+arguments[0]);
}
var t=new Date().getTime();
setTimeout(add,1000);
对延迟进行修改测试出了以下数据:延迟时间 弹出内容
1000 1009,8
2000 1998 -2
3000 3006 6
发现一个小规律:
执行时间差-那个奇怪的参数约等于延迟时间。那个参数有点像setTimeout的执行的时间,但怎么会有负值呢?
它的意义大概就是实际延迟时间与设定延迟时间的差值吧。这个问题就到这里吧。
还有一个问题,能否在IE下实现如FF下setTimeout的功能呢?网上查了一下,已经有人去实现了这个,偶对其做简单改造,发布出来,其中对于计算差值的一行在实际中可以去掉,这里只是为了模拟和FF下完全一样的接口效果。
实现方法也并不复杂,主要利用了JS的call和apply,对call和apply不熟悉的可以先查看一下他们的用法。
<script type="text/javascript">
<!--
(function(){
var st = window.setTimeout;
window.setTimeout = function(fn, mDelay) {
var t=new Date().getTime();
if(typeof fn == 'function'){
var args = Array.prototype.slice.call(arguments,2);
var f = function(){
args.push(new Date().getTime()-t-mDelay); //该行用于实现对实际延迟和设定延迟的差值,同FF的最后一个参数,无实际意义
fn.apply(null, args)
};
return st(f, mDelay);
}
return st(fn,mDelay);
}
})();
function test(x,y,z){
alert(x+","+y+","+z);
}
setTimeout(test,1000,'arg1','arg2');
//-->
</script>