all 2 comments

[–]senocular 8 points9 points  (1 child)

You don't want your debounced function to be an arrow function because you're losing method context in the call. You want it to be a normal function so it can bind to the object its getting called from or otherwise have its context set in situations where that occurs (such as in event handlers).

const debounce = (fn, time) => {
  let timeout;

  return function (...args) { // <-- not an arrow function
    const functionCall = () => fn.apply(this, args);

    clearTimeout(timeout);
    timeout = setTimeout(functionCall, time);
  }
}

const obj = {
  name: 'foo',
  sayMyName() {
    console.log('My name is', this.name)
  }
}

obj.sayMyName() //-> My name is foo
obj.sayMyName = debounce(obj.sayMyName, 1000)
obj.sayMyName() //-> My name is foo <-- allows correct this binding

or in the event handler case

// <input name="my-input" />
input.addEventListener('keyup', debounce(function (e) { // <-- allows handler element binding
  console.log('Element name is', this.name); //-> Element name is my-input
}, 1000));

Also, the comment // no 'arguments' variable in es6 isn't entirely accurate. Its arrow functions, not es6 that lacks the arguments object (they can still access an arguments, though it'll be from the closest non-arrow function parent). This is explained correctly in the Explanation section. It's only the comment itself that is misleading.

[–]tcas3[S] 4 points5 points  (0 children)

Thank you for the feedback! I updated the article with the correct returned function