JS进阶——防抖,节流

惰性载入函数

如果if语句没必要每次都执行,代码可以更快运行。解决办法就是惰性载入函数
1.在函数被调用时再处理函数
创建一个变量,if中的每个分支都会为变量赋值,有效覆盖了原有的函数,最后一步就是调用新赋的函数。
2.在声明函数时就指定适当的函数。1.返回一个函数,2.匿名自执行。

函数绑定

使用bind进行绑定。bind()中使用了apply改变了fn的上下文环境。arguments是内部匿名函数的,而非bind的。所以可以拿到对应的event参数。

unction bind(obj,context){
    return function(){
        obj.apply(context, arguments)
    }
}

函数柯里化

柯里化是指这样一个函数(假设叫做createCurry),他接收函数A作为参数,运行后能够返回一个新的函数。并且这个新的函数能够处理函数A的剩余参数。
** 通用的封装**

var currying = function(fn) {
    // args 获取第一个方法内的全部参数
    var args = Array.prototype.slice.call(arguments, 1)
    return function() {
        // 将后面方法里的全部参数和args进行合并
        var newArgs = args.concat(Array.prototype.slice.call(arguments))
        // 把合并后的参数通过apply作为fn的参数并执行
        return fn.apply(null, newArgs)
    }
}

bind

function bind(fn,content){
var args=Array.prototype.slice.call(arguments,2);
return function(){
fn.apply(content,args.concat(Array.prototype.slice.call(arguments)));
}}
// 支持多参数传递
function progressCurrying(fn, args) {
    var _this = this
    var len = fn.length;
    var args = args || [];

    return function() {
        var _args = Array.prototype.slice.call(arguments);
        Array.prototype.push.apply(args, _args);
        // 如果参数个数小于最初的fn.length,则递归调用,继续收集参数
        if (_args.length < len) {
            return progressCurrying.call(_this, fn, _args);
        }
        // 参数收集完毕,则执行fn
        return fn.apply(this, _args);
    }
}

防篡改对象

不可扩展对象
不可扩展(不可添加、可以删除、可以修改、可以查)
【增、删、改、查】 --> 【删、改、查】
Object.preventExtension(obj) 禁止扩展
Object.isExtensible(obj) 判断是否可以扩展
密封的对象
(不可添加、不可删除、可以修改、可以查)密封对象不可扩展,不可删除
【增、删、改、查】 – Object.seal() --> 【改、查】
Object.seal() 密封对象
Object.isSealed 对象是否密封
冻结的对象
(不可添加、不可删除、不可修改、可以查)
【增、删、改、查】 – Object.freeze() --> 【查】
Object.freeze()
Object.isFrozen()

函数防抖

防抖和节流是针对响应跟不上触发频率这类问题的两种解决方案。 在给DOM绑定事件时,有些事件我们是无法控制触发频率的。 如鼠标移动事件onmousemove, 滚动滚动条事件onscroll,窗口大小改变事件onresize,瞬间的操作都会导致这些事件会被高频触发。 如果事件的回调函数较为复杂,就会导致响应跟不上触发,出现页面卡顿,假死现象。

定义:多次触发事件后,事件处理函数只执行一次,并且是在触发操作结束时执行。
原理:对处理函数进行延时操作,若设定的延时到来之前,再次触发事件,则清除上一次的延时操作定时器,重新定时。

let timer;
window.onscroll  = function () {
    if(timer){
        clearTimeout(timer)
    }
    timer = setTimeout(function () {
        //滚动条位置
        let scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
        console.log('滚动条位置:' + scrollTop);
        timer = undefined;
    },200)
}


不适用:
当我们做图片懒加载(lazyload)时,需要通过滚动位置,实时显示图片时,如果使用防抖函数,懒加载(lazyload)函数将会不断被延时,只有停下来的时候才会被执行,对于这种需要实时触发事件的情况,就显得不是很友好了。

var timer = false;
document.getElementById("debounce").onscroll = function(){
    clearTimeout(timer); // 清除未执行的代码,重置回初始化状态
    timer = setTimeout(function(){
        console.log("函数防抖");
    }, 300);
};  

函数节流

定义:触发函数事件后,短时间间隔内无法连续调用,只有上一次函数执行后,过了规定的时间间隔,才能进行下一次的函数调用。原理:对处理函数进行延时操作,若设定的延时到来之前,再次触发事件,则清除上一次的延时操作定时器,重新定时。

var canRun = true;
document.getElementById("throttle").onscroll = function(){
    if(!canRun){  // 判断是否已空闲,如果在执行中,则直接return
        return;
    }
    canRun = false;
    setTimeout(function(){
        console.log("函数节流");
        canRun = true;
    }, 300);
};

图中每一个断点都代码触发了一次函数,但是触发函数时只在奇数时执行,偶数时不执行,断点间的时间间隔为50ms。
函数节流

let startTime = Date.now(); //开始时间
let time = 500; //间隔时间
let timer;
window.onscroll = function throttle(){
    let currentTime = Date.now();
    if(currentTime - startTime >= time){
        let scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
        console.log('滚动条位置:' + scrollTop);
        startTime = currentTime;
    }else{
        clearTimeout(timer);
        timer = setTimeout(function () {
            throttle()
        }, 50);
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
JavaScript中的防抖节流是为了控制函数的执行频率,以提高性能和优化用户体验。 防抖(debounce)是指在一定的时间间隔内,只执行最后一次操作。引用提供了一个自定义的防抖函数示例。该函数接受两个参数:待执行的函数和延迟时间。在函数调用时,如果在延迟时间内再次触发了函数调用,则会清除之前的定时器,重新设置一个新的定时器,以延迟函数的执行。 节流(throttle)是指在一定的时间间隔内,限制函数的执行频率。引用和提供了两个不同的节流函数示例。这些节流函数都可以指定一个时间间隔,只有在这个时间间隔内函数没有被执行过才能继续执行。其中,引用实现了一个基于定时器的节流函数,而引用则是一个基础版的节流函数,使用了时间戳来判断是否达到执行条件。 需要注意的是,防抖节流可以根据具体的需求和场景来选择使用,以达到更好的效果。防抖适用于需要等待用户停止操作后才执行的场景,而节流适用于需要限制函数执行频率的场景。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [JavaScript 防抖节流的实现](https://blog.csdn.net/weixin_43853746/article/details/122654312)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [【JavaScript】防抖(debounce)、节流(throttling)](https://blog.csdn.net/qq_46658751/article/details/123386755)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值