命名空间Javascript中的递归函数

时间:2014-05-01 00:38:11

标签: javascript

为了组织起见,我有一个我已命名的网站(NS.something.functionA()等)。我希望在这个命名空间的Javascript中有一个递归函数,但是当函数试图调用自身时,我得到一个undefined is not a function错误。

http://jsfiddle.net/fmpeyton/Jwz6g/

var timeoutInt = 2000;
var NS = {};
var resultsElement = document.getElementById('results');

NS.recur1 = (function(){
    setTimeout(function(){
        NS.recur1();
        resultsElement.innerHTML += 'recur1 re-occuring!<br/>';
    }, timeoutInt);
})();

(function recur2(){
    setTimeout(function(){
        recur2();
        resultsElement.innerHTML += 'recur2 re-occuring!<br/>';
    }, timeoutInt);
})();

NS.recur3 = (function(){
    (function realRecur3(){
        setTimeout(function(){
            realRecur3();
            resultsElement.innerHTML += 'recur3 re-occuring!<br/>';
        }, timeoutInt);
    })()
})();

recur1()是我遇到问题的功能。 recur2()是我之前在JS中看过递归工作的方式。 recur3()是我正在玩的一个想法(不理想,但绝对是一个解决方案)。

有没有办法让递归函数recur1()起作用?

3 个答案:

答案 0 :(得分:3)

(function recur1(){
    setTimeout(function(){
        recur1();
        resultsElement.innerHTML += 'recur1 re-occuring!<br/>';
    }, timeoutInt);
})();

会这样做。

您可以命名函数表达式,当您这样做时,名称将绑定到函数体中函数表达式的结果。

language spec解释了

  

制作    FunctionExpression function 标识符(FormalParameterList opt ){ FunctionBody }   评估如下:

     

...

     

调用envRec的CreateImmutableBinding(N)具体方法,将Identifier的String值作为参数传递。

答案 1 :(得分:3)

NS.recur1 = (function(){
  setTimeout(function(){
    NS.recur1();
    resultsElement.innerHTML += 'recur1 re-occuring!<br/>';
  }, timeoutInt);
})(); // << This () invokes the function you just wrapped

所以NS.recur1不是&#34;函数&#34;,而是返回该调用。

因此,当您致电NS.recur1()时,您正在针对recur1()致电undefined,因为调用并未返回任何内容。

简单的替代方法是在分配时不调用,但在稍后的某个时间

NS.recur1 = function(){
  setTimeout(function(){
    NS.recur1();
    resultsElement.innerHTML += 'recur1 re-occuring!<br/>';
  }, timeoutInt);
};

NS.recur1(); // begin recursion

答案 2 :(得分:-2)

第一个recur1不是一个函数,它是一个闭包,函数和闭包(执行自己包装一些内部逻辑的函数)是不同的东西,而你正在弄乱它们。

我认为你想要的是声明函数,然后调用它们中的一个,触发由一个名为timeoutInt的标志定时的循环递归,这样你就可以创建用timeoutInt毫秒更新某些东西的代码流。

 var timeoutInt = 2000;
 var NS = {};
 var resultsElement = document.getElementById('results');

 NS.recur1 = function(){
     setTimeout(function(){
         NS.recur1();
         resultsElement.innerHTML += 'recur1 re-occuring!<br/>';
     }, timeoutInt);
 };

 NS.recur2 = function(){
     setTimeout(function(){
         NS.recur2();
         resultsElement.innerHTML += 'recur2 re-occuring!<br/>';
     }, timeoutInt);
 };

 NS.recur3 = function(){
     setTimeout(function(){
         NS.recur3();
         resultsElement.innerHTML += 'recur3 re-occuring!<br/>';
     }, timeoutInt);
 };

使用上面的代码,从这一点开始。

以下是帮助您的进一步推动:http://jsfiddle.net/Jwz6g/1/(工作示例)