【问题标题】:what's the point of declaring args and context in a debounce function在 debounce 函数中声明 args 和 context 有什么意义
【发布时间】:2020-01-22 00:00:01
【问题描述】:

我遇到过几次自定义的去抖函数,本教程的大部分内容都是这样编写去抖函数的

function debounce(func, wait, immediate) {
var timeout;
return function() {
    var context = this, args = arguments;
    var later = function() {
        timeout = null;
        if (!immediate) func.apply(context, args);
    };
    var callNow = immediate && !timeout;
    clearTimeout(timeout);
    timeout = setTimeout(later, wait);
    if (callNow) func.apply(context, args);
};

};

我对声明上下文和参数的含义感到困惑,并在匿名返回函数中使用 apply。声明这两个变量,后面再用apply,把这两个传入debounce中的待执行函数有什么意义?

对我来说,我只能看到它允许我以这种方式传递参数:

function myFunc(name) {
  console.log('hello',name)
}
debounce(myFunc, 100)('Josh');

但是和直接传给myFunc不一样吗,这样写:

debounce(myFunc('Josh'), 100);

为什么我们需要在这里使用apply?

【问题讨论】:

  • 您可以轻松试用您的版本:它不起作用。
  • 请记住,debounce 应该用作const f = debounce(myFunc, 100); f('John'); f('Luke'); f('Jane'); …,然后是对f 的更多调用。这根本不适合你的风格(即使你做了f = debounce(() => { myFunc('Josh') }, 100))。

标签: javascript debounce


【解决方案1】:

这样做的原因是 debounce 应该在指定的时间后调用某个函数。为了调用一个函数,它需要一个函数引用。如果您要执行以下操作:

debounce(myFunc('Josh'), 100);

myFunc('Josh') 实际上并不是对函数myFunc 的引用,而是对函数myFunc 的评估。用一个例子来详细说明这一点可能会很有用。

// this is a function definition
function add(num1, num2) {
  return num1 + num2;
}

console.log(add); // `add` is a function reference
console.log(add(1, 1)); // 2 is the result of the function's evaluation

鉴于上述示例,如果您执行了debounce(add(1, 1), 100);,您将要求去抖动函数在 100 毫秒不活动后调用值 2。您真正想做的是调用函数add,但为了这样做,您需要传递对函数的引用:debounce(add, 100)。现在的问题是我们无法将参数传递给 add 函数,而这正是柯里化派上用场的地方。

声明匿名函数是一种控制将要调用的方法的范围和上下文的方法。它创建一个闭包,其中所有变量和状态将继续存在,直到函数执行完毕。例如,如果您将 debounce 函数应用于输入字段,则每次用户触发 debounce 函数时参数可能不同。将args 保留在闭包中允许每个新函数“记住”它自己的参数。

至于你为什么要使用.apply,这仅仅是因为参数是一个值数组,所以如果你想用多个单独的参数调用你的方法,你需要使用.applythis example

【讨论】:

    【解决方案2】:

    你不能将参数直接传递给要执行的函数,因为这些参数只有在函数 debounce 被调用时才能实现,这些参数实际上是在 debounce 函数内部隐式传递给函数的 这里

    return function ()
    

    即使此函数似乎没有接收任何参数,您也可以将参数传递给它并通过调用此变量来检索这些参数:

    args = arguments // here they are
    

    对于最后一个问题,为什么需要使用 apply?

    这是因为每当你在处理一些隐式调用时,就像

    document.addEventListener('click', myFunc.bind(this)) // Implicit here
    

    或者像你的情况

    debounce(myFunc, 100)
    

    必须将必要的上下文绑定到此隐式调用。

    在您的情况下,您仅在实际调用 debounce 时才会收到此上下文。 使用此实现,传递给内部函数的上下文与您调用 debounce 函数的上下文相同。 如果你没有使用 apply,内部函数的上下文将被限制在 debounce 函数的范围内,而不是 debounce 被调用的范围

    【讨论】:

      猜你喜欢
      • 2011-10-23
      • 1970-01-01
      • 2016-12-09
      • 1970-01-01
      • 2012-09-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-03
      相关资源
      最近更新 更多