8

With this debounce function:

function debounce(fn, delay) {
    var timer
    return function () {
      var context = this
      var args = arguments
      clearTimeout(timer)
      timer = setTimeout(function () {
        fn.apply(context, args)
      }, delay)
    }
  }

can someone explain why I should use fn.apply(context,args) instead of fn() only?

I know .apply will change the context and var context = this will make the context always be the same as the context in fn(). I can't find a scenario where using fn() and fn.apply(context, args) gives a different result.

Can someone give me an example?

colourCoder
  • 1,394
  • 2
  • 11
  • 18
Moon
  • 790
  • 1
  • 8
  • 19
  • You have to do this, obviously, because you want to execute function in a caller context. https://javascript.info/ – Ievgen Oct 16 '20 at 18:17
  • You could not use debounce to decorate an object method otherwise. – Jared Smith Oct 16 '20 at 18:19
  • You don't need to use `this` or `apply` unless your are using classes/prototypes/object methods. If you don't use `this` you can just do what you're suggesting. – arc Jul 21 '21 at 11:07

1 Answers1

6

Consider the following class:

class Foo {
  constructor () {
    this.a = 'a';
    this.bar = debounce(this.bar, 500);
  }

  bar () {
    console.log(this.a);
  }
}

const foo = new Foo();
foo.bar();
foo.bar();
foo.bar();

So what gets logged, and when, and how many times? You are going to see one value logged, one time, about half a second after the last call. With the definition you posted you'll see a. If you omit the contextual part you'll see undefined:

function debounceWithoutCtx(fn, delay) {
    var timer
    return function (...args) {
      clearTimeout(timer)
      timer = setTimeout(function () {
        fn(...args)
      }, delay)
    }
 }
  
Jared Smith
  • 19,721
  • 5
  • 45
  • 83