为什么这里使用func.apply()传递this会失败?

// 节流装饰器
    function throttle(f, ms) {
        let firstRun = false;
        let lastArgs;
        let savedThis;

        return function () {
            lastArgs = arguments;
            savedThis = this;
            if (!firstRun) {
                f.apply(savedThis, lastArgs);
                firstRun = 1;
                setInterval(() => f.apply(savedThis, lastArgs), ms);
            }
        }
    }

    let ff = {
        log: "",
        f: str => {
            this.log += str;
            alert(this.log);
        }
    }

    // 包装器
    ff.f = throttle(ff.f, 1000);
    ff.f('once');

预期的结果是
once
onceonce
onceonceonce...
实际上是
undefinedonce
undefinedonceonce
undefinedonceonceonce...

一晚上没解决,求助各位大佬们了

之所以写的这么奇怪是因为原题有个测试点过不去,我就改出上面那样的代码

原题链接:https://zh.javascript.info/ta...

未过的测试点

阅读 1.5k
1 个回答

这个节流函数没有问题,问题在于ff.f方法的定义上,箭头函数不会自己创建this,而是从自己的作用域链的上一层继承this,由于ff.f方法是在最顶层作用域调用,所以这里的this是指向全局对象window而不是ff对象,你把ff.f改成下面这样就可以了。可以参考下MDN的文档:箭头函数

function throttle(f, ms) {
    let firstRun = 0;
    let lastArgs;
    let savedThis;
    // 将定时器的最小间隔时间限定在1000毫秒
    ms = Math.max(ms, 1000);
    return function() {
        lastArgs = arguments;
        savedThis = this;
        if (!firstRun) {
            f.apply(savedThis, lastArgs);
            firstRun++;
            let timer = setInterval(() => {
                if (firstRun++ < 3) {
                    f.apply(savedThis, lastArgs);
                } else {
                    firstRun = 0;
                    clearInterval(timer);
                }
            }, ms);
        }
    }
}
let ff = {
    log: "",
    f(str) {
        this.log += str;
        alert(this.log);
    }
};
// 包装器
ff.f = throttle(ff.f, 1000);
ff.f('once');
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏