js防抖封装

"Hello World, Hello Blog"

Posted by wudimingwo on December 15, 2018

版本1.0

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function debounce (handle,duration) {
            var duration = duration || 1000; 
            var timer = null;
          	function newHandle () {
            var self = this;
            var args = arguments;
          	clearTimeout(timer);
          	timer = setTimeout(function () {
          		handle.apply(self,args);
          	},duration);
          	}
          	return newHandle;
          }

版本2.0 封装在原型链

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Function.prototype.debounce = function (duration) {
          	var fn = this;
          	var duration = duration || 1000;
          	var timer = null;
          	function newFn () {
          		var self = this;
          		var args = arguments;
            	clearTimeout(timer);
            	timer = setTimeout(function () {
            		fn.apply(self,args);
            	},duration);
          	}
          	return newFn;
          }

从形式上看,防抖是,一个函数(fn)调用防抖函数(debounce),并返回新的函数(newFn). newFn 和 fn 有很大的区别.

  1. 如果fn是有数据返回的,newFn是无法返回数据的.因为setTimeout里的回调是无法返回值的. 2.如果fn当做构造函数.newFn是无法返回实例对象的.因为setTimeout…

我们假设非要能够返回,怎么做? 能不能做?

版本3.0

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
Function.prototype.debounce = function (duration) {
          	var fn = this;
          	var duration = duration || 1000;
          	var timer = null;
          	var flag = true;
          	newFn.prototype = fn.prototype;// 这里可以用圣杯继承代替.
          	function newFn () {
          		var self = this;
          		var args = arguments;
          		if(flag){
          		  fn.apply(self,args);
          		  flag = false;
          		}else{
          		  clearTimeout(timer);
          		  timer = setTimeout(function () {
          		  	fn.apply(self,args);
          		  	flag = true; 
          		  },duration);
          		}
          	}
          	return newFn;
          }

这个跟版本2.0的功能不太相同.
这里用了一个锁,flag
完成的功能是,第一次会立即执行函数,第二次开始会启动防抖.
顺带的,也能解决上面两个问题.
不过大多数情况下,没有上面两个问题的需求,所以用版本2.0应该是足够的.