我有这个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
的超时。为什么在放入匿名函数时不立即调用它?这与封闭有什么关系吗?因为看起来我不得不创建一个闭包,但我还没有想出足够的知识来确定它们。
任何想法都会受到赞赏。
答案 0 :(得分:6)
在您第一次setTimeout()
来电时,请:
that.destroy(terms, curTerm + 1)
是一个函数调用表达式。对其进行评估,以构建一组参数值来调用setTimeout()
。
当你将它包装在一个匿名函数中时,该(匿名)函数被而不是调用,因为你没有用函数调用运算符作为后缀 - 带括号的参数列表。
因此:形式的表达
something ( p1, p2, ... pn )
表示在评估参数列表中的每个参数后调用“something”引用的函数,然后在更大的表达式上下文继续时使用该值。 始终表示在JavaScript中。没有语法可以说“这是我希望你稍后调用的函数,以及一些要传递的参数”。 (现在有一个函数 - 在函数原型上进行.bind()
- 但没有特殊的语法。)
答案 1 :(得分:1)
这只是JavaScript语法的一部分。
function name() {}
声明一个函数,name()
调用它。您还可以使用语法(function (){})()
立即调用匿名函数。
另请注意,您可以传递函数名称,否则匿名函数将适用于:
setTimeout(that.destroy, 1500)
当然,在这种情况下,您无法更改参数。
答案 2 :(得分:1)
当JavaScript解释器看到someFunction(param)
时,它立即调用方法someFunction
并将参数param
传递给它。换句话说,当你这样做时:
setTimeout(someFunction(param), 1000);
...你正在通过setTimeout传递someFunction(param)的结果。您可以将someFunction作为第一类成员传递,如下所示:
setTimeout(someFunction, 1000, param);
这样,您就可以通过setTimeout传递someFunction的定义。请注意,在这种情况下通过param
将无法在IE中工作。
另请参阅http://www.helephant.com/2008/08/19/functions-are-first-class-objects-in-javascript/。