防抖节流里的this传递

今天心血来潮重写防抖节流,写着写着突然冒出一个问题,为什么执行函数的时候要用apply呢,为什么不直接写fn(...args)呢?

js 复制代码
        //防抖
        function debounce(fn, wait, immediate = false) {
            let timer = null;

            return function (...args) {
                if (immediate && timer === null) {
                    fn.apply(this, args);
                }

                clearTimeout(timer);
                timer = setTimeout(() => {
                    timer = null;
                    if (!immediate) {
                        fn.apply(this, args);  //为什么要用apply?
                    }
                }, wait)
            }
        }
        
        let a = 1;
        function onClick() {
            console.log(this)
            console.log(a++)
        }
        document.addEventListener('click', debounce(onClick, 1000, true))

虽然关于this的指向也背的七七八八,但不得不说,在真实的开发中,有时候还是会被绕进去。那么今天就来扫荡一下迷雾吧。

首先,在这个例子当中,给document绑定了一个click事件,事件处理函数是debounce(onClick, 1000, true),也就是防抖函数这个高阶函数的返回值。

如果这里没有防抖,而是直接这样写:

js 复制代码
document.addEventListener('click', debounce(onClick, 1000, true))

那么onClick内部的this会指向谁呢?答案是指向document。因为浏览器的事件绑定机制是,在哪个元素上绑定了事件函数,该函数的this就指向这个元素。相当于浏览器执行了onClick.call(document, event)。

经过debounce包装了onClick后,它内部的this应该与没包装的时候一样,指向document。

但是,现在onClick与document之间的直接联系已经被切断了,相当于之前是手拉手,现在中间硬插了一个人进来:

js 复制代码
// document--onClick  之前
// document--debounce--onClick  现在

于是,我们就只能通过插入的这个人来进行一个传递。现在,事件处理函数从onClick变成了debounce(onClick, 1000, true),而后者就等同于debounce函数返回的那个函数,因此这个返回函数的this指向了document:

所以现在事情就好办了,只需要在这个返回函数里面调用fn的时候,把this指向传递进去就可以了。可以用apply,也可以用call。而如果不这样做的话,就会出现下图的情况,this没有正确传递:

相关推荐
JustHappy39 分钟前
古法编程秘籍(七):互联网到底是什么?把两台电脑怎么说话搞懂就够了
前端·后端·网络协议
老毛肚42 分钟前
jeecg-boot-base-core 02 day
javascript·python
snow@li42 分钟前
SEO-文章标题:写文章时候,分类+主标题+大纲+解释 作为标题 / 不点进去也知道全文覆盖什么 / 标题即架构
前端
kyriewen2 小时前
Git Commit 前自动修复代码风格?配置 Husky + lint-staged,从此 CR 只聊逻辑
前端·git·面试
小和尚同志2 小时前
AI 自动化测试探索(一):Playwright MCP
前端·人工智能·aigc
老马识途2.02 小时前
在AI的帮助下理解spring的启动过程
java·前端·spring
徐小夕3 小时前
Loop Engineering 深度解析与实战指南(全网最全)
前端·算法·github
运筹vivo@3 小时前
Python ContextVar 底层机制与内存模型拆解
前端·数据库·python
#麻辣小龙虾#4 小时前
基于vue3.0开发一款【固废与废气运维管理系统】(支持源码)
前端·vue.js·vue3
Cosolar4 小时前
Docsify零构建文档站完全指南:从快速搭建到企业级部署
前端·开源·github