setTimeout()自我调用函数内的递归函数
我想分发我的代码作为自我调查的匿名函数,因为我看到很多。另外,在我的代码中,我必须监视另一个lib加载,所以我可以在它可用时使用它。setTimeout()自我调用函数内的递归函数
(function(window, document, undefined) {
staffHappens();
var initMyLib = function() {
if (typeof(myLib) == 'undefined') {
setTimeout("initMyLib()", 50);
} else {
useMyLib();
}
}
moreStaffHappens();
initMyLib(); //-> initMyLib is undefined
})(this, document);
这个错误怎么会发生? initMyLib应该在封闭(自我封闭)函数的范围内吗?
变化setTimeout("initMyLib()", 50);
到setTimeout(initMyLib, 50);
当你传递一个字符串作为参数,它会尝试当超时被触发,以评估它,但它会在全球范围内运行。而你的方法在全球范围内不存在。
你也可以使用一个真正的匿名功能,避免范围的问题:
(function() {
if(typeof(myLib) == 'undefined')
setTimeout(arguments.callee, 50);
else
// loaded
})()
一个有效的解决方案,但由于'arguments.callee'在最近的javascript版本中被弃用,所以你应该避免使用它,并使用建议的命名函数..这也可以用'(function name(){'然后使用'setTimeout(name,50);' – 2012-01-11 15:47:08
@Gaby aka G. Petrioli:我知道,'callee'仍然是一个值得了解的简洁功能 – georg 2012-01-11 17:16:16
确实是... – 2012-01-11 21:43:52
要读这个答案了一些线索:recursive function vs setInterval vs setTimeout javascript
这是该答案的代码示例:
/*
this will obviously crash... and all recursion is at risk of running out of call stack and breaking your page...
function recursion(c){
c = c || 0;
console.log(c++);
recursion(c);
}
recursion();
*/
// add a setTimeout to reset the call stack and it will run "forever" without breaking your page!
// use chrome's heap snapshot tool to prove it to yourself. :)
function recursion(c){
setTimeout(function(c){
c = c || 0;
console.log(c++);
recursion(c);
},0,c);
}
recursion();
// another approach is to use event handlers, but that ultimately uses more code and more resources
这应该不会影响“undefined”的位置,尽管... – Ktash 2012-01-11 15:25:03
@kTash,不是它不应该,但是您确定undefined部分来自该行而不是执行超时脚本? – 2012-01-11 15:27:03
我不知道。这是他所说的发生的路线,所以我认为他已经完成了调试以便弄清楚这些......这是我首先想到的,但是如果它发生在指定的行而不是超时,那么我我不确定这是对的。我只是在大声思考 – Ktash 2012-01-11 15:30:44