en.javascript.info/1-js/06-advanced-functions/09-call-apply-decorators/02-delay/solution.md

883 B

The solution:

function delay(f, ms) {

  return function() {
    setTimeout(() => f.apply(this, arguments), ms);
  };

}

let f1000 = delay(alert, 1000);

f1000("test"); // shows "test" after 1000ms

Please note how an arrow function is used here. As we know, arrow functions do not have own this and arguments, so f.apply(this, arguments) takes this and arguments from the wrapper.

If we pass a regular function, setTimeout would call it without arguments and this=window (assuming we're in the browser).

We still can pass the right this by using an intermediate variable, but that's a little bit more cumbersome:

function delay(f, ms) {

  return function(...args) {
    let savedThis = this; // store this into an intermediate variable
    setTimeout(function() {
      f.apply(savedThis, args); // use it here
    }, ms);
  };

}