Javascript闭包和递归

cer*_*eny 2 javascript recursion closures

我一直在更具体地阅读编程闭包概念,尤其是与Javascript有关的概念.我还没有完全理解它与我多年来一直在写的Javascript代码有什么不同.我也理解递归的概念,但我想知道,闭包和递归是如何相似的?我是否正确理解递归本身就是一种闭包?

关闭:

function init() {
    var name = "Stack Overflow";
    function displayName() {
        alert(name);
    }
    displayName();
}
init();
Run Code Online (Sandbox Code Playgroud)

递归:

function factorial(num) {
    if(num < 0)
        return -1;

    else if(num == 0)
        return 1;

    else
        return (num * factorial(num - 1));
}

alert(factorial(8));
Run Code Online (Sandbox Code Playgroud)

我想我已经开始明白闭包只不过是在函数中有一个函数,内部函数可以通过作用域访问外部函数.可能会有递归闭包吗?我的意思是,虽然我的递归示例也不是关闭的例子,但它至少会发生吗?我试图理解递归和闭包是如何相似,不同,或者它们是否可以被所有人比较.有没有例子可以描述这个?

Tha*_*you 7

一个封闭是一个简单的函数或过程,"关闭了"环境(它的身体).在代码中,init,displayName,和factorial全封闭.当您想要创建闭包时,可以使用JavaScript function关键字(或者现在我们=>在ES6中有箭头功能).

递归是程序重复自身的效果


我一直在读一本新书,它谈到了一些相关的主题.我想我会在这里分享一些笔记,以防你感兴趣.

这是计算阶乘的递归函数.它与你的一样,但是以一种非常不同的方式.让我们来看看!

function factorial(x) {
  if (x < 0) throw Error("Cannot calculate factorial of a negative number");
  function iter(i, fact) {
    return i === 0 ? fact : iter(i-1, i*fact);
  }
  return iter(x, 1);
}

factorial(6); // 720
Run Code Online (Sandbox Code Playgroud)

将它与您在上面定义的^.^进行比较.请注意,即使它是递归的,它也不会factorial再次调用自身().这使用线性迭代过程,消耗线性空间和时间.对函数的评估看起来像这样

factorial(6);
  iter(6, 1);
  iter(5, 6*1); 
  iter(4, 5*6);
  iter(3, 4*30);
  iter(2, 3*120);
  iter(1, 2*360);
  iter(0, 1*720);
// => 720
Run Code Online (Sandbox Code Playgroud)

将其与您的功能过程进行比较.这是你的样子

factorial(6);
(6 * factorial(5));
(6 * (5 * factorial(4)));
(6 * (5 * (4 * factorial(3))));
(6 * (5 * (4 * (3 * factorial(2)))));
(6 * (5 * (4 * (3 * (2 * factorial(1))))));
(6 * (5 * (4 * (3 * (2 * 1)))));
// => 720
Run Code Online (Sandbox Code Playgroud)

请注意,作为n增加,n!添加另一个堆栈调用.这是一个线性递归过程.对于较大的值n,此方法使用显着更多的空间来计算相同的结果.