Marlin
Marlin

Reputation: 749

Function Definitions as Arguments

var cancel = setTimeout(function(){clearTimeout(cancel);}, 500);

var cancel = setTimeout(clearTimeout(cancel), 500);

Scholastic question: The first of these two expressions work, while the second does not. The setTimeout() method is accepting a function and a duration as its arguments and both of these examples are clearly providing that. The only difference is that the first is a function definition while the second is a function invocation.

If functions designed to take a function as an argument can only handle function definitions, how do you go about providing that function with the variables it may need? For example:

stop = function(y){clearInterval(y)};
count = function(x){
    var t = 0,
    cancel = setInterval(function(){console.log(++t);},1000);
    setTimeout(stop(cancel),x);
};
count(5000);

The function above doesn't work because it's invoking the function

stop = function(){clearInterval(cancel)};
count = function(x){
    var t = 0,
    cancel = setInterval(function(){console.log(++t);},1000);
    setTimeout(stop,x);
};
count(5000);

The function above doesn't work because the stop() doesn't have access to the cancel variable.

Thank you in advance for attempting to educate me on the work-around for this type of issue.

Upvotes: 0

Views: 63

Answers (4)

Alexander Gessler
Alexander Gessler

Reputation: 46607

Local variables are always injected into nested scopes, for example those introduced by function declarations via function () { }. This is what is commonly called a closure and it forms an important tool in Javascript programming.

Therefore, setTimeout( function() { stop(cancel); },x); will do, the inner function has access to the cancel variable defined in the outer scope (it can even change its value).

Upvotes: 0

Keith.Abramo
Keith.Abramo

Reputation: 6955

Try passing in the cancel variable to the anonymous function.

stop = function(cancel){clearInterval(cancel)};
count = function(x){
    var t = 0,
    cancel = setInterval(function(){console.log(++t);},1000);
    setTimeout(stop(cancel),x);
};
count(5000);

Upvotes: 0

Jeremy
Jeremy

Reputation: 792

You get around it exactly as you have in the first line of code by wrapping the function call with an anonymous function.

Upvotes: 1

Darin Dimitrov
Darin Dimitrov

Reputation: 1038710

The setTimeout() method is accepting a function and a duration as its arguments and both of these examples are clearly providing that. The only difference is that the first is a function definition while the second is a function invocation.

Yes but when you invoke a function you return the result which could be a string, integer, etc..., so you are no longer passing a function pointer but some string, integer, ... which is not what the setTimeout function expects as first argument.

Think of the second example like this:

var result = clearTimeout(cancel); // result is now an integer
setTimeout(result, 500); // invalid because setTimeout expects a function pointer

If functions designed to take a function as an argument can only handle function definitions, how do you go about providing that function with the variables it may need?

You could use closures:

var stop = function(y) { clearInterval(y); };
var count = function(x) {
    var t = 0,
    var cancel = setInterval(function() { console.log(++t); }, 1000);
    setTimeout(function() { stop(cancel); }, x);
};
count(5000);

or simply:

var count = function(x) {
    var t = 0,
    var cancel = setInterval(function() { console.log(++t); }, 1000);
    setTimeout(function() { clearInterval(cancel); }, x);
};
count(5000);

Upvotes: 2

Related Questions