我有一些JavaScript代码,看起来像:
function statechangedPostQuestion()
{
//alert("statechangedPostQuestion");
if (xmlhttp.readyState==4)
{
var topicId = xmlhttp.responseText;
setTimeout("postinsql(topicId)",4000);
}
}
function postinsql(topicId)
{
//alert(topicId);
}
我得到一个错误,topicId没有定义
在我使用setTimeout()函数之前,一切都在工作。
我希望我的postinsql(topicId)函数在一段时间后被调用。
我该怎么办?
我的回答:
setTimeout((function(topicId) {
return function() {
postinsql(topicId);
};
})(topicId), 4000);
解释:
创建的匿名函数返回另一个匿名函数。该函数可以访问最初传递的topicId,因此不会出错。第一个匿名函数被立即调用,并传入topicId,因此具有延迟的注册函数在调用时可以通过闭包访问topicId。
OR
这基本上可以转换为:
setTimeout(function() {
postinsql(topicId); // topicId inside higher scope (passed to returning function)
}, 4000);
编辑:我看到了同样的答案,所以看看他的。但我没有偷他的答案!我只是忘了看。阅读解释,看看它是否有助于理解代码。
Hobblin已经就这个问题发表了评论,但它确实应该是一个答案!
使用Function.prototype.bind()是最干净和最灵活的方法(能够设置this上下文的额外奖励):
setTimeout(postinsql.bind(null, topicId), 4000);
欲了解更多信息,请参阅这些MDN链接:
https://developer.mozilla.org/en/docs/DOM/window.setTimeout#highlighter_547041
https://developer.mozilla.org/en/docs/JavaScript/Reference/Global_Objects/Function/bind#With_setTimeout
我知道它很老了,但我想加入我喜欢的味道。
我认为实现这一点的一种相当易读的方法是将topicId传递给一个函数,该函数反过来使用参数在内部引用主题ID。即使外部的topicId不久后将被更改,该值也不会改变。
var topicId = xmlhttp.responseText;
var fDelayed = function(tid) {
return function() {
postinsql(tid);
};
}
setTimeout(fDelayed(topicId),4000);
或短:
var topicId = xmlhttp.responseText;
setTimeout(function(tid) {
return function() { postinsql(tid); };
}(topicId), 4000);
用一个简单的带有两个参数的加法函数来回答这个问题。
var x = 3, y = 4;
setTimeout(function(arg1, arg2) {
return () => delayedSum(arg1, arg2);
}(x, y), 1000);
function delayedSum(param1, param2) {
alert(param1 + param2); // 7
}