2

我有这个 Javascript 函数:

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);
            }
        });
    };

我遇到的问题是setTimeout(function () {that.destroy(terms, curTerm + 1);}, 1500);. 最初我有setTimeout(that.destroy(terms, curTerm + 1), 1500);,但它没有设置它刚刚调用的超时that.destroy。为什么放入匿名函数时不立即调用它?这和闭包有关系吗?因为似乎我必须创建一个闭包,但我对它们的了解还不够,无法确定。

任何想法将不胜感激。

4

3 回答 3

6

在您的第一次setTimeout()通话中,这是:

that.destroy(terms, curTerm + 1)

是一个函数调用表达式。对其进行评估是为了构建要调用的参数值集setTimeout()

当您将它包装在匿名函数中时,不会调用该(匿名)函数,因为您没有使用函数调用运算符作为后缀 - 带括号的参数列表。

因此:形式的表达

something ( p1, p2, ... pn )

表示在评估参数列表中的每个参数后调用“某物”引用的函数,然后在更大的表达式上下文进行时使用该值。它总是意味着在 JavaScript 中。没有语法可以说“这是我希望你稍后调用的函数,以及要传递的一些参数”。(现在有一个函数可以做到这一点——.bind()在函数原型上——但没有特殊的语法。)

于 2013-01-16T23:27:34.640 回答
1

这只是 JavaScript 语法的一部分。

function name() {}声明一个函数并name()调用它。您还可以使用语法立即调用匿名函数(function (){})()

另请注意,您可以在匿名函数适合的地方传递函数名称,例如:

setTimeout(that.destroy, 1500)

当然,在这种情况下你不能改变论点。

于 2013-01-16T23:28:20.243 回答
1

当 JavaScript 解释器看到someFunction(param)时,它立即调用该方法someFunction并将参数传递给它param。换句话说,当你这样做时:

setTimeout(someFunction(param), 1000);

...您将 setTimeout 传递给 someFunction(param) 的结果。您可以改为将 someFunction 作为一等成员传递,如下所示:

setTimeout(someFunction, 1000, param);

这样,您将 setTimeout 传递给 someFunction 的定义。请注意,param在这种情况下传递在 IE 中不起作用。

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

于 2013-01-16T23:30:49.777 回答