如果我们正常调用该函数而不是“apply”,那么在去抖动的实现中是否存在潜在的陷阱?

问题描述 投票:0回答:1

我们经常发现去抖实现与

func.apply(this, args)
我想这只是为了确保“this”指向返回的内部函数的上下文。

const debounce = function (func, wait = 1000) {
    let timer = null;

    return function (...args) {
      clearTimeout(timer);

      timer = setTimeout(() => {
        func.apply(this, args)
      }, wait);
    };
  };
  
  const handleSearch = function(param1, param2){
     console.log(param1 + param2);
  }
  
  let debouncedFunc = debounce(handleSearch, 1000);
  debouncedFunc("hello ", "world");

但是,如果我们简单地使用

args
调用该函数,而不用担心
apply
this
,我会得到相同的结果。那么这种方法是否存在任何潜在的陷阱,因为我们通常像前者一样实施?

     const debounce = function (func, wait = 1000) {
        let timer = null;

        return function (...args) {
          clearTimeout(timer);

          timer = setTimeout(() => {
            func(...args)
          }, wait);
        };
      };
      
      const handleSearch = function(param1, param2){
         console.log(param1 + param2);
      }
      
      let res = debounce(handleSearch, 1000);
      res("hello ", "world");

javascript
1个回答
0
投票

您将失去对

this
的访问权限。当您想要对尝试从对象访问数据的对象中的方法进行反跳时,这可能至关重要。考虑一个简单的例子,以下可能是您想要做的真正的计数器,并确保双击之类的事情不会重新触发它:

const myObj = { 
  data: 41, 
  increment: debounce(function() { 
    this.data++; 
  }, 100)
}

使用

.apply(this, args)
1 时,效果完全符合预期:

const debounce = function (func, wait = 1000) {
  let timer = null;

  return function (...args) {
    clearTimeout(timer);

    timer = setTimeout(() => {
      func.apply(this, args)
    }, wait);
  };
};

const myObj = { 
  data: 41, 
  increment: debounce(function() { 
    this.data++; 
  }, 100)
}

myObj.increment(); //increment call is debounced and will apply in 100ms
myObj.increment(); //second call is within the debounce period, thus ignored

setTimeout(
  //the number printed is 42
  () => console.log(`after debounce period: ${myObj.data}`),
  150
);

当不向去抖动函数提供

this
的值时,结果为关闭:

const debounce = function (func, wait = 1000) {
  let timer = null;

  return function (...args) {
    clearTimeout(timer);

    timer = setTimeout(() => {
      func(...args)
    }, wait);
  };
};

const myObj = { 
  data: 41, 
  increment: debounce(function() { 
    this.data++; 
  }, 100)
}

myObj.increment(); //increment call is debounced and will apply in 100ms
myObj.increment(); //second call is within the debounce period, thus ignored

setTimeout(
  //the number printed is 41
  () => console.log(`after debounce period: ${myObj.data}`),
  150
);

严格模式中,相同的代码甚至会抛出错误,因为

this
将是
undefined

"use strict";

const debounce = function (func, wait = 1000) {
  let timer = null;

  return function (...args) {
    clearTimeout(timer);

    timer = setTimeout(() => {
      func(...args)
    }, wait);
  };
};

const myObj = { 
  data: 41, 
  increment: debounce(function() { 
    this.data++; 
  }, 100)
}

myObj.increment(); //increment call is debounced and will apply in 100ms
myObj.increment(); //second call is within the debounce period, thus ignored

setTimeout(
  //the number printed is 41
  () => console.log(`after debounce period: ${myObj.data}`),
  150
);

1 作为旁注,使用

.apply(this, arguments)
可能更容易 - 不需要可变参数,因为
arguments
对象
已经提供了它们。但总体来说影响不大。

© www.soinside.com 2019 - 2024. All rights reserved.