js防抖封装

版本1.0

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
封装在原型链

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

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应该是足够的.

你可能感兴趣的:(js防抖封装)