码迷,mamicode.com
首页 > 编程语言 > 详细

JavaScript递归原理

时间:2018-03-07 00:45:15      阅读:151      评论:0      收藏:0      [点我收藏+]

标签:使用   模式   class   递归   适合   script   新手   表达式   访问   

JavaScript递归是除了闭包以外,函数的又一特色呢.很多开发新手都很难理解递归的原理,我在此总结出自己对递归的理解.

 

所谓递归,可以这样理解,就是一个函数在自身的局部环境里通过自身函数名又调用,如此反复,直到条件不满足,返回最终结果的一种情形.最简单的一个示例代码如下:

 

function fn(a){
   return a <= 1 ? a = 1 : a * fn(a - 1); 
}

 

这也是一个最经典的递归阶乘函数了,虽然这行代码表面上看起来没什么问题,但在执行如下代码,则会出现错误.

 

var otherfn = fn;
fn = null;
otherfn(5);//出错,fn is not a function

  

以上将定义的递归阶乘函数fn()保存在变量otherfn中,然后将fn()函数设置为null,也就是说,这样就断掉了对原始函数fn()的引用,因此在调用otherfn()函数时候就会报错.毕竟调用otherfn()实际上就相当于是调用fn()函数,而fn()函数已经被解除了引用,所以自然会报一个fn 不是一个函数的错误呢.

 

那么,有没有办法解决呢?

 

JavaScript的arguments.callee就可以解决这个问题.argumens.callee实际上就是指向一个函数的指针,因此,只要将以上代码修改成如下所示:

 

function fn(a){
   return a <= 1 ? a = 1 : a * arguments.callee(a - 1);
}

 

这样,通过arguments.callee代替了函数名fn,就保证了引用不会被解除,因此无论怎么调用该函数就不会出问题了.

 

因此,在编写递归函数时,使用arguments.callee总是比直接用函数名更好一点.

 

不过,使用arguments.callee有个缺点,那就是在严格模式下,是无非访问arguments.callee的,因此就需要使用命名函数表达式来达到与这个指针带来的效果呢.代码如下:

 

var fn = (function f(a){
  return a <= 1 ? a = 1 : a * f(a - 1);
});

 

以上代码创建了一个命名为f的函数表达式,然后将它赋值给一个fn变量.因此即便把这个函数表达式赋值给另一个变量,这个函数也仍然可以正常调用.而且这种做法不仅适合非严格模式,也同样适合严格模式.

JavaScript递归原理

标签:使用   模式   class   递归   适合   script   新手   表达式   访问   

原文地址:https://www.cnblogs.com/eveningwater/p/8519669.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!