js节流代码的疑问

新手上路,请多包涵

看到一个实现节流的方法,但是其中有两个地方不太理解。

/**
 * 函数节流
 */
export function throttle(fn,delay){
    var lastTime;
    var timer;
    var delays = delay || 200;
    console.log('页面创建是就被打印出来',delays,arguments)
    return function() {
      var args = arguments;
      console.log(this,arguments)
      // 记录当前函数触发的时间
      var nowTime = Date.now();
      if (lastTime && nowTime - lastTime < delays) {
        clearTimeout(timer);
        timer = setTimeout(function () {
          // 记录上一次函数触发的时间
          lastTime = nowTime;
          // 修正this指向问题
          fn.apply(this, args);
        }, delays);
      }else{
        lastTime = nowTime;
        fn.apply(this, args);
      }
    }
  } 
// 调用方法
  import { throttle } from "../../utils";
  methods: {
    onAdd: throttle(function(i) {
      this.num += i;
    }, 3000)
  }

我试了一下,发现在页面创建后就会打印出第一条内容。触发onAdd时只执行retyrn function中的内容,这是为什么?
第二个问题:在定时器里为什么还要写apply方法,而且这一步还没被执行?

阅读 1.5k
3 个回答

JS闭包了解下?
throttle是一个函数,很明显onAdd属性的值是throttle函数的返回值.throttle在这里被显式的调用了,并且将返回的值作为onAdd方法。也就是为什么也没创建会打印第一条内容,因为这里是函数调用啊。而实际onAdd方法是throttle函数里return的那个函数。
最后,为什么apply注释不是写的很清楚吗——修正this指向问题。至于为什么要修正。this了解下?

你的第一个问题显而易见,我都不知道怎么回答;

{...
  methods: {
    onAdd: throttle(function(i) {
      this.num += i;
    }, 3000)
  }
}

相当于: 下面的

const onAdd = throttle(function(i) {
      this.num += i;
    }, 3000);

{...
  methods: {
    onAdd,
  }
}

这么看会舒服点,实际上上面代码跟这个一个意思,整个表达式就是一个方法执行,所以方法内部的log当然执行了,执行完以后返回了一个玩意儿是方法,这里的onAdd就是个方法, 下面赋值到methods的属性上, 啥时候用?(触发的时候方法执行)。

至于第二个问题: 这里是为了把 arguments 这个传递下去,当参数个数确定的时候,你可以一个一个把参数传进去,参数不确定的时候就得用apply,这几乎是唯一的办法。

我怎么觉得这个 throttle 更应该叫做 debounce , 而且 setTimeout 里函数的 this 都丢失了, 还用这个 :)

第一次的时候 lastTime 为空就执行 else 里的
假设连续执行就走 if 判断

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题