-3

generally for js debounce function, a simple implement goes like

function debounce(func, wait) {
  let timerId = null;
  return function (...args) {
  console.log('args',args);
    clearTimeout(timerId);
    timerId = setTimeout(() => func.apply(this, args), wait);
  }
}

and when you use it, you can do things like

var random = function() {console.log(arguments)};
var test = debounce(random, 1000);
test(1,2,3);

my question is, how does the returned function inside debounce function can get all attributes that gets passed into test function (here being 1,2,3) through arguments object? I feel like it might have to do with closure, but can anyone explain?

I've also created a jsFiddle for simpler view https://jsfiddle.net/u4n07veb/22/

Another question would be in this js fiddle, my console.log args can print 1,2,3, since 1,2,3 is what I pass to test function, but would it also be possible to get 4,5,6 inside the debounce function? Since 4,5,6 is the parameters I pass to the callback function of the debounce function?

Shuwei
  • 774
  • 6
  • 7

1 Answers1

0

Though the arguments special object does exist in JavaScript, in the implementation of debounce above the function arguments are instead retrieved via a rest parameter.

The difference is minimal - arguments is not a true Array but instead an Array-like object, whereas the ...args rest parameter method will retrieve an actual Array - but it's one worth mentioning.

The actual passing through of these arguments happens when Function.prototype.apply is called, which allows a function to be called with a given value of this and a specified array of arguments. It's a sibling to the similar Function.prototype.call, which takes each argument to passed through as a separate parameter.

So in your example, you call test(1, 2, 3) and that executes the function that was returned by debounce(random, 1000). That function gets its arguments as an Array via the ...args rest parameter, and then passes that array through to the random function via func.apply(this, args).

To answer your question about passing a different set of parameters through, I recommend you try it and see. But the answer is yes: with this setup the debounced function is able to pass through any number of arguments.

Closures aren't directly relevant to how the arguments are passed through here. They are relevant in a different way, however, in that the timerId variable created when debounce is called is kept in a closure so that later attempts to call the debounced function will access it again, which is what allows the innards of this debounce implementation to clear the timeout it had created during its previous execution.

Mark Hanna
  • 3,206
  • 1
  • 17
  • 25
  • First of all, thank you for your answer! The point I'm suffering with is that why the returned function inside debounce can get all passed-in arguments through arguments object. I mean I know what arguments object is and how it works, but I just couldn't wrap my head around why would the returned function inside debounce can get it... maybe because when I call test(1,2,3), the returned function inside debounce is getting called with parameters 1,2,3? – Shuwei Apr 07 '22 at 15:12
  • 1
    When you call `test(1, 2, 3);` you are calling the function returned by `debounce`. That function collects all its arguments via a rest parameter, `...args`, which is then passed to the original function via `func.apply(this, args)`. Then that original function is able to access the same arguments that were passed through here with `args` by using its internal `arguments` object. – Mark Hanna Apr 07 '22 at 20:12