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);
}
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);
}
};
}
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);
}
};
}
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();