Search code examples
javascript

Debounce on function defined in an object cannot access object's context


I was trying to implement a debounce function which works fine if tied to global functions

Function.prototype.debounce = function(debounceTime) {
  let timeoutIdentifier;
  return (...args) => {
    clearTimeout(timeoutIdentifier);
    setTimeout(() => {
      this(args)
    }, debounceTime)
  }
}

var debouncedFunction = (function() {
  console.log('hi');
}).debounce(2000); // logs 'hi' after 2 seconds

debouncedFunction();

Unfortunately I am not able to make it work if used with a function defined as a property of an object

var obj = {
  name: 'saksham',
  printName: (() => {
    console.log(this.name)
  }).debounce(3000)
}

obj.printName(); // prints nothing

Tried binding the objects context to printName() as well but it did not work. Any possible solutions?


Solution

  • Use a regular function to declare your object method, so it doesn't capture this context when it is declared (currently it's being assigned to window). Also, use the Function.prototype.apply() in your debounce function in order to set the right this context in the method call:

    Function.prototype.debounce = function(debounceTime) {
      let timeoutIdentifier;
      const self = this;
      return function(...args) {
        clearTimeout(timeoutIdentifier);
        timeoutIdentifier = setTimeout(() => {
          self.apply(this, args)
        }, debounceTime)
      }
    }
    
    var obj = {
      name: 'saksham',
      printName: (function() {
        console.log(this.name)
      }).debounce(3000)
    }
    
    obj.printName(); // saksham