防抖节流里的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没有正确传递:

相关推荐
phltxy1 天前
Vue 核心特性实战指南:指令、样式绑定、计算属性与侦听器
前端·javascript·vue.js
Byron07071 天前
Vue 中使用 Tiptap 富文本编辑器的完整指南
前端·javascript·vue.js
css趣多多1 天前
地图快速上手
前端
zhengfei6111 天前
面向攻击性安全专业人员的一体化浏览器扩展程序[特殊字符]
前端·chrome·safari
码丁_1171 天前
为什么前端需要做优化?
前端
Mr Xu_1 天前
告别硬编码:前端项目中配置驱动的实战优化指南
前端·javascript·数据结构
Byron07071 天前
从 0 到 1 搭建 Vue 前端工程化体系:提效、提质、降本实战落地
前端·javascript·vue.js
哆啦code梦1 天前
前端存储三剑客:localStorage、sessionStorage与Cookie解析
前端·前端存储
徐小夕@趣谈前端1 天前
Web文档的“Office时刻“:jitword共建版2.0发布!让浏览器变成本地生产力
前端·数据结构·vue.js·算法·开源·编辑器·es6
Data_Journal1 天前
如何使用 Python 解析 JSON 数据
大数据·开发语言·前端·数据库·人工智能·php