简体   繁体   English

命名空间Javascript中的递归函数

[英]Recursive function in namespaced Javascript

I have a site that I've namespaced ( NS.something.functionA() , etc) for sake of organization. 为了组织起见,我有一个命名空间为( NS.something.functionA()等)的网站。 I want to have a recursive function within this namespaced Javascript, but when the function tries to call itself, I get an undefined is not a function error. 我想在此命名空间的Javascript中包含一个递归函数,但是当该函数尝试调用自身时,我得到的undefined is not a function错误。

http://jsfiddle.net/fmpeyton/Jwz6g/ 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() is the function I am having a problem with. recur1()是我遇到问题的函数。 recur2() is how I've seen recursion work before in JS. recur2()是我之前在JS中看到递归工作的方式。 recur3() was an idea I was playing around with (not ideal, but definitely a solution). recur3()是我一直在考虑的想法(不理想,但绝对是解决方案)。

Is there any way to make the recursive function recur1() work? 有什么方法可以使递归函数recur1()工作?

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

will do it. 会做的。

You can name function expressions, and when you do, the name is bound to the result of the function expression in the function's body. 您可以命名函数表达式,然后,将其绑定到函数主体中函数表达式的结果。

The language spec explains 语言规范说明

The production FunctionExpression : function Identifier ( FormalParameterList opt ) { FunctionBody } is evaluated as follows: 产生的FunctionExpressionfunction 标识符 (FormalParameterList opt ){ FunctionBody }评估如下:

... ...

Call the CreateImmutableBinding(N) concrete method of envRec passing the String value of Identifier as the argument. 调用envRec的CreateImmutableBinding(N)具体方法,将Identifier的String值作为参数传递。

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

So NS.recur1 is not a "function", but the return of that invocation. 因此, NS.recur1不是“函数”,而是该调用的返回。

So when you call NS.recur1() , you are calling recur1() against undefined , since the invocation doesn't return anything. 因此,当您调用NS.recur1() ,您将针对undefined调用recur1() ,因为调用不会返回任何内容。

Simple alternative would be to not invoke at assignment, but at some later point 一种简单的选择是不在赋值时调用,而是在稍后的某个时刻调用

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

NS.recur1(); // begin recursion

First recur1 is not a function, it's a closure, function and closure (function that executes himself wrapping some internal logic) are different things and you are messing them both. 首先recur1不是一个函数,它是一个闭包,函数和闭包(函数执行自身包装一些内部逻辑)是不同的事情,并且您都将它们弄乱了。

I think that what you want is to declare the functions, and then, call one of them, to trigger a cyclic recursion timed by a flag called timeoutInt, so you are kind of creating code flows that update something with timeoutInt milliseconds. 我认为您想要的是声明这些函数,然后调用其中一个函数,以触发由名为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);
 };

Use the code above and start from this point. 使用上面的代码,从这一点开始。

Here is a further push to help you out: http://jsfiddle.net/Jwz6g/1/ (working example) 这是进一步帮助您的方法: http : //jsfiddle.net/Jwz6g/1/ (工作示例)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM