2

Can not undestand why the arguments of functions f1000 and f1500 are not passed to the wrapper function delay.

For now I get undefined instead of the right results from test and test2.

function f(x) {
  console.log( x );
}

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

var f1000 = delay(f, 1000);
var f1500 = delay(f, 1500);

f1000("test"); // must display "test"
f1500("test2"); // must display "test2"
Sviat Kuzhelev
  • 1,758
  • 10
  • 28

1 Answers1

4

You are passing the wrong arguments.

You are getting undefined because the arguments object is a local variable.
The callback function passed to setTimeout has no arguments, hence you get undefined.

You can close (closure) over the arguments from the outer scope and pass them on:

function f(x) {
  console.log(x);
}

function delay(f, ms) {
  return function() {
    var args = arguments;
    setTimeout(function() {
      var delayed = f.apply(this, args);
      return delayed;
    }, ms);
  }
}

var f1000 = delay(f, 1000);
var f1500 = delay(f, 1500);

f1000("test"); // 
f1500("test2"); //
Sagiv b.g
  • 30,379
  • 9
  • 68
  • 99
  • @savig_b.g You are right! But I do not understand why we can not push arguments directly into the timer? Thanks – Sviat Kuzhelev Dec 29 '17 at 22:13
  • 1
    That's because [the `arguments` object is a local variable](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/arguments). the callback function passed to `setTimeout` has no arguments, hence you get undefined. one way to get a hold of an outer scope `arguments` is to use a closure (like we did in the example). i've updated my answer to explain this as well. – Sagiv b.g Dec 29 '17 at 22:18
  • Thanks a lot for explanation! I probably need more practice in closures functions :) – Sviat Kuzhelev Dec 29 '17 at 22:24
  • 1
    @SviatKuzhelev That's always good to practice :) . as for closures it's quite simple (and brilliant). a closure is when a function access a variable outside it's [lexical scope](https://stackoverflow.com/questions/1047454/what-is-lexical-scope), even if the function is executed outside that same lexical scope like we have in our example because of the async nature of `setTimeout`. – Sagiv b.g Dec 29 '17 at 22:35