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

当你传递一个字符串作为参数,它会尝试当超时被触发,以评估它,但它会在全球范围内运行。而你的方法在全球范围内不存在。


演示在http://jsfiddle.net/gaby/zVr7L/

+0

这应该不会影响“undefined”的位置,尽管... – Ktash 2012-01-11 15:25:03

+0

@kTash,不是它不应该,但是您确定undefined部分来自该行而不是执行超时脚本? – 2012-01-11 15:27:03

+0

我不知道。这是他所说的发生的路线,所以我认为他已经完成了调试以便弄清楚这些......这是我首先想到的,但是如果它发生在指定的行而不是超时,那么我我不确定这是对的。我只是在大声思考 – Ktash 2012-01-11 15:30:44

你也可以使用一个真正的匿名功能,避免范围的问题:

(function() { 
    if(typeof(myLib) == 'undefined') 
     setTimeout(arguments.callee, 50); 
    else 
     // loaded 
})() 
+1

一个有效的解决方案,但由于'arguments.callee'在最近的javascript版本中被弃用,所以你应该避免使用它,并使用建议的命名函数..这也可以用'(function name(){'然后使用'setTimeout(name,50);' – 2012-01-11 15:47:08

+0

@Gaby aka G. Petrioli:我知道,'callee'仍然是一个值得了解的简洁功能 – georg 2012-01-11 17:16:16

+0

确实是... – 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