防抖

用户在规定时间间隔内持续完成一件事,不会触发函数执行。

立即防抖

//func 执行的函数
// wait 延迟时间
function debounce(func, wait) {
   
    var timeout = null;
    var context = this;
    var args = arguments;
    return function () {
   
        if (timeout) clearTimeout(timeout);
        var callNow = !timeout;
        timeout = setTimeout(function () {
   
            timeout = null; //没有任何效果只是一种习惯,js中的GC机制会把值为null,undefined的直接回收。
        }, wait)
        if (callNow) func.apply(context, args)
    }
}

函数会先执行一次,之后在规定时间间隔内持续操作不会触发函数执行。

非立即防抖

function debounce(func, wait) {
   
    var timeout = null;
    var context = this;
    var args = arguments;
    return function () {
   
        if (timeout) clearTimeout(timeout);
        timeout = setTimeout(function () {
   
            func.apply(context, args)
        }, wait);
    }
}

用户在一定时间间隔内持续操作,不会触发函数。

双剑合璧版

function debounce(func, wait, immediate) {
   
    var timeout;
    return function () {
   
        var context = this;
        var args = arguments;
        if (timeout) clearTimeout(timeout);
        if (immediate) {
   
            var callNow = !timeout;
            timeout = setTimeout(function () {
   
                timeout = null;
            }, wait)
            if (callNow) func.apply(context, args)
        }
        else {
   
            timeout = setTimeout(function () {
   
                func.apply(context, args)
            }, wait);
        }
    }
}

节流

如果一个函数持续的,频繁的触发,那么就让他在一定的时间间隔后触发。

时间戳版
function throttle(func, wait) {
   
    var previous = 0;
    return function () {
   
        var now = Date.now();
        var context = this;
        var args = arguments;
        if (now - previous > wait) {
   
            func.apply(context, args);
            previous = now;
        }
    }
}
定时器版
function throttle(func, wait) {
   
    var timeout;return function() {
   
        var context = this;
        var args = arguments;
        if (!timeout) {
   
            timeout = setTimeout(function(){
   
                timeout = null;
                func.apply(context, args)
            }, wait)
        }}
}

双剑合璧版

* @desc 函数节流
* @param func (function) 函数
* @param wait (number) 延迟执行毫秒数
* @param type  (number) 1 表时间戳版,2 表定时器版
​
function throttle(func, wait ,type) {
   
    if(type===1){
   
        var previous = 0;
    }else if(type===2){
   
        var timeout;
    }return function() {
   
        var context = this;
        var args = arguments;
        if(type===1){
   
            var now = Date.now();if (now - previous > wait) {
   
                func.apply(context, args);
                previous = now;
            }
        }else if(type===2){
   
            if (!timeout) {
   
                timeout = setTimeout(function(){
   
                    timeout = null;
                    func.apply(context, args)
                }, wait)
            }
        }}
}

时间戳版和定时器版的节流函数的区别就是,时间戳版的函数触发是在时间段内开始的时候,而定时器版的函数触发是在时间段内结束的时候。

总结

防抖:函数执行一次

节流:函数在一定时间内再次执行