Search code examples
javascriptsettimeout

setTimeout function parameters undefined (JS)


I have not been able to find a proper explanation to this.

function subtract(x, y) {
    setTimeout(function(x, y) {
      document.write(x - y);
  }, 1000);
}

subtract(1, 1);

This writes NaN to the document because the x and y parameters passed to setTimeout are undefined. You'd think that x and y should be integer 1 and it's within scope of the subtract function. The following snippet works perfectly fine and writes integer 0 as expected:

function subtract(x, y) {
    setTimeout(function() {
      document.write(x - y);
  }, 1000);
}

subtract(1, 1);

Removing the parameters seem to solve the problem. Why?


Solution

  • You have not passed the parameters to the function callback, when the callback is eventually invoked by the setTimeout the x and y are undefined.

    So you see NaN as the output because undefined - undefined is NaN.

    setTimeout takes the parameters of the function callback you have passed after the delay argument, in your case after 1000.

    Without passing the parameters, the x and y variables is scoped to the function callback. It won't take the values from the outer scope as it is shadowed by the function parameters you have given.

    function subtract(x, y) {
        setTimeout(function(x, y) {
          document.write(x - y);
      }, 1000, 1, 1);
    }
    
    subtract(1, 1);

    You can also use Function.prototype.bind to pass the parameters to the callback function.

    The bind takes the this context as the first argument and the rest of the arguments are the parameters to the function. In my example I have given null as the this context:

    function subtract(x, y) {
        setTimeout(function(x, y) {
          document.write(x - y);
      }.bind(null,1,1), 500);
    }
    
    subtract(1, 1);