setTimeout setIterval,这两个计时器函数对于Javascript程序员来说肯定不陌生,它们是实现一些动态效果和数据交互的重要工具,但是原生函数不能传参,而且作用域统统指向window,这里可以对其进行一个简单的封装,先是setTimeout 函数相关扩展:

defer : function(time, scope){
var slice = Array.prototype.slice,
method
= this,
args
= slice.call(arguments, 2);
if(typeof time !== 'number' || time <= 0)
return method;
setTimeout(
function(){
return method.apply(scope || method || window, args );
}, time);
}

//Test code: function.defer(1000, this, arguments);

这基本就是delegate原型函数的改版,很容易理解,函数方法只需简单调用defer方法,即可实现setTimeout的功能,同时绑定作用域并传参.

下面关于setTimeout的应用稍微有点儿复杂,很多应用中,有时候大家并不想让某个函数连续执行,比如mousemove/mouseover 监听函数,如果执行复杂操作的话,连续执行会消耗很大内存,这就需要每次执行函数之间强制加入一个间隔,间隔时间内不能再次执行这个函数,下面上代码:

buffer : function(time, scope){
var slice = Array.prototype.slice,
args
= slice.call(arguments, 2),
method
= this,
invoked
= false;
return function(){
var callargs = Array.prototype.slice.call(arguments,0).concat(args);
if(!invoked){
invoked
= true;
setTimeout(
function(){
invoked
= false;
}, time);
return method.apply(scope || method || window, callargs);
}
};
}
// Test code: function.buffer(1000, this);

该方法只是返回一个函数变量,并不会马上执行,特别作为一个事件触发函数,呵呵代码希望大家自己琢磨,原理其实并不难,我也是半个小时之内编写并测试成功的

下面是setIterval的扩展,setIterval是一个连续触发,循环必须靠clearInterval函数来执行

createInterval : function(frequency, scope){
var interval,
method
= this,
callargs
= Array.prototype.slice.call(arguments, 3);
return {
run :
function(){
interval
= setInterval(method.delegate(scope), frequency);
},
stop :
function(){
clearInterval(interval);
}
};
}
// Test code: var f = function.createInterval(1000, this); f.run(); f.stop();
这个原形函数返回一个新对象,其中有run stop 方法来对原函数的循环调用进行控制,呵呵形式比较奇怪,不过我个人很推崇这种写法,有点儿Java thread的感觉哦