0

我在javascript中有这两个递归函数。第一个函数以从右到左的顺序返回输入数字的数字第二个函数以从左到右的顺序返回它们。

function first(n){
    if(n > 0){
        m = Math.floor( n/10 );
        v = ( n - m * 10 ) + " " + first(m);
        return v;
    }
    return "";
}



function second(n){
    if(n > 0){
        m = Math.floor( n/10 );
        v = second(m) + " " + ( n - m * 10 );
        return v;
    }
    return "";
}

第一个函数的结果是

7 6 1 

第二个函数的结果是

1 16 167

但我期待这个

1 6 7 

我在 PHP 和 JAVA 中测试了类似的代码,它运行良好。大概问题出在 Javascript 的闭包中。但我不知道如何解决它。

4

1 回答 1

3

这非常简单:您正在使用隐含的全局变量:

function second(n)
{
    if(n > 0)
    {
        m = Math.floor( n/10 );
        //m is changing here ------\\will use lowest value of m
        v = second(m) + " " + ( n - m * 10 );
        return v;
    }
    return "";
}

修复方法是:

function second(n)
{
    if(n > 0)
    {
        //make declare it in the scope itself
        var m = Math.floor( n/10 );
        v = second(m) + " " + ( n - m * 10 );
        return v;
    }
    return "";
}

这仍然给你留下了邪恶的隐含 global v。如果我是你,我也会v在当地申报

function second(n)
{
    var m, v = '';
    n = +(n);//coerce to number
    if (n > 0)
    {
        m = Math.floor(n/10);
        v = second(m) + ' '+ (n-m*10);
    }
    return v;
}

此功能按预期工作。
这个问题实际上与闭包无关,但它是由JS 解析表达式/名称的方式引起的。
将其与 JS 如何处理递归函数相结合,您将获得简单明了的输出。

JS 还没有真正的递归调用堆栈。上次我检查时,递归调用被有效地短路(~= goto's)。我记得读过 Douglas Crockford 关于这个主题的一些东西,关于它与调用堆栈有关。
虽然 ES5 的严格模式确实引入了 TCO,但它应该在 2013 年底之前实现(ES6 - Harmony)。我已经链接到这里的几个网站,如果你想了解更多关于此事的信息

于 2013-07-24T09:03:00.730 回答