简体   繁体   中英

Why do I have to enclose a Javascript function call in an anonymous function for it to not be called immediately?

I have this Javascript function:

function Card(term, def, terms, curTerm) {
    this.term = term;
    this.def = def;
    this.terms = terms;
    this.curTerm = curTerm;

    this.show = function() {
        that = this;
        var html = createCard(that.term, that.def);
        $('body').append(html);
        $('input[type=text]').focus();
        $('.answer').on('click', function(event) {
            event.preventDefault();
            answer = $(this).parent().serializeArray()[0].value;

            // answer correct
            if (that.term === answer) {
                $('.card').addClass('correct');
                $('form').replaceWith('<h2>Correct! ' + that.term + '</h2>');
                setTimeout(function () {that.destroy(terms, curTerm + 1);}, 1500);

            // answer incorrect
            } else {
                $('.card').addClass('incorrect');
                $('form').replaceWith('<h2>Incorrect! ' + that.term + '</h2>');
                setTimeout(function () {that.destroy(terms, curTerm);}, 1500);
            }
        });
    };

The line I am having issues with is setTimeout(function () {that.destroy(terms, curTerm + 1);}, 1500); . Originally I had setTimeout(that.destroy(terms, curTerm + 1), 1500); , but it didn't set the timeout it just called that.destroy . Why does it not call it immediately when put in the anonymous function? Does this have anything to do with closures? because it seems like I am having to create a closure, but I haven't figured out enough about them to know for sure.

Any thoughts would be appreciated.

In your first setTimeout() call, this:

that.destroy(terms, curTerm + 1)

is a function call expression. It's evaluated in order to build the set of parameter values to call setTimeout() .

When you wrap it in an anonymous function, that (anonymous) function is not called, because you don't suffix it with the function call operator — the parenthesized list of parameters.

Thus: an expression of the form

something ( p1, p2, ... pn )

means to invoke the function referenced by "something" after evaluating each of the parameters in the argument list, and then use that value as the larger expression context proceeds. It always means that in JavaScript. There's no syntax to say "here's the function I want you to call later, and some parameters to pass". (There's a function to do that now — .bind() on the Function prototype — but no special syntax .)

This is just part of the JavaScript syntax.

function name() {} declares a function and name() calls it. You can also call anonymous functions immediately with the syntax (function (){})() .

Also note that you can pass function names where an anonymous function would otherwise be appropriate, as in:

setTimeout(that.destroy, 1500)

Of course you can't change the arguments in that case.

When the JavaScript interpreter sees someFunction(param) , it immediately calls the method someFunction and passes it the parameter param . In other words, when you do:

setTimeout(someFunction(param), 1000);

... you're passing setTimeout the result of someFunction(param). You can instead pass someFunction as a first-class member like this:

setTimeout(someFunction, 1000, param);

This way, you're passing setTimeout the definition of someFunction. Beware that passing param in this case won't work in IE.

Also, see http://www.helephant.com/2008/08/19/functions-are-first-class-objects-in-javascript/ .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM