You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为函数属性编写节流装饰器?解决闭包与上下文问题

解决节流装饰器的this指向问题

你的问题核心是setTimeout回调里的this丢失了原方法的上下文,同时还有参数处理的小问题,修正方案如下:

方案1:使用箭头函数继承外层this

箭头函数不会绑定自身的this,会沿用外层函数的上下文,这里外层就是包装方法的this(也就是类实例):

function throttle(timecount) {
    return function (value, { name, kind }) {
        const origin = value;
        if (kind === 'method') {
            return function (...args) { // 用剩余参数收集所有调用参数
                setTimeout(() => {
                    origin.apply(this, args); // 箭头函数继承外层的this
                }, timecount);
            };
        }
    };
}

class D {
    message = "hello!";

    @throttle(1000)
    m() {
        console.log('execute', this.message);
    }
}

const y = new D();
y.m(); // 1秒后输出 "execute hello!"

方案2:提前保存上下文到变量

如果需要兼容不支持箭头函数的环境,可以在包装函数里把this存到变量,在setTimeout回调里使用这个变量:

function throttle(timecount) {
    return function (value, { name, kind }) {
        const origin = value;
        if (kind === 'method') {
            return function (...args) {
                const self = this; // 保存当前实例的上下文
                setTimeout(function () {
                    origin.apply(self, args); // 使用保存的上下文
                }, timecount);
            };
        }
    };
}

额外注意点

  • 原代码里setTimeout的回调函数声明了args参数,会覆盖外层的args,导致传递给原方法的参数错误,必须去掉这个参数。
  • 包装函数的参数要用...args剩余语法收集所有调用参数,保证原方法能接收到正确的参数。

内容的提问来源于stack exchange,提问作者Eric Wang

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 09:25:00