文档章节

递归以及闭包

梦在风中
 梦在风中
发布于 2016/04/10 10:48
字数 1282
阅读 1603
收藏 55

闭包以及递归的深刻理解

        前言:建议新学者先懂了作用域之后再去了解闭包;

        作用域和预解析以及复杂的面试题 http://my.oschina.net/zzjweb/blog/651937

        在我们平时的工作可能递归用的不是很多,闭包可能我们在不经意间就使用了,所以建议大家有必要的去了解一下。如果有新学者,自己建议还是有必要去看一下作用域链的,有很多息息相关的东西存在。

        递归指函数自己调用自己。

        当然我们在使用递归时也要注意一些问题:

  1.   自己调用自己就相当于循环一样,以此来到达一些便利;

  2.   我们在使用递归时必须要有跳出的条件,不然就会出现死递归;

  3.   递归在计算的时候会极大的消耗计算机的性能,在计算的值比较小的时候我们可以忽略,当我们使用递归需要循环的值比较大的时候,我们就不得不考虑其的计算效率,那将是一个比较庞大的计算量

  4. 如果我们想深刻的理解递归的话,个人建议可以看一些高数之类的书籍,毕竟在递归中,其中的划归还是很重要的,如果没有一些数学的铺垫个人觉得还是比较费劲的

        下面通过几个例子来给大家讲解一下普通的递归:

   1.  求兔子序列(斐波那契数列)的前几项;

var fib = function ( n ) {
   if ( n === 0 || n === 1 ) return 1;
   return fib( n - 1 ) + fib( n - 2 );
}; 

    2.  求n^m次方;   

function fn(a,b){
   if(b==0)return 1;
   return fn(a,b-1)*a;
}

    3.   求等差数列前几项的和;       

function fn(n) {
    if (n == 1)return 1;
    return fn(n - 1) + (2 * n - 1)
}

        在操作递归时,递归会把自己参数中的值进行传递,直到我们传递的值达到我们设置的跳出条件时才会停止传递,而后面的公式指的是与我们需要得到的值进行的相对应操作,当我们写在函数中的值就相当于每一个传递的实参。

       但是递归的性能消耗是我们不得不重视的,那么下面通过对于数据的缓存来给大家介绍一下如何让递归减少性能的消耗。

        通过斐波那契数列来给大家举例说明

        通过上述的代码我们可以使递归在计算时减少很大一部分的性能消耗。

        闭包指的被函数分割而成的作用域,从而形成的被保护的私有数据,这个就被我们称之为闭包。

        我们要做的就是通过一些办法来得到闭包内部的数据。

        下面给大家讲解一下闭包:

function foo() {
   var num = Math.random();
   return num;
}

var res = foo();  
var r1 = foo();
var r2 = foo();

        正常我们觉得从函数中reture出来的值是一样的,当我们打印随机数时,我们会发现值其实是不相同的。只是我们平时在使用闭包的时候,return得到的值是同一个,所以会误认为得到的值是同一个。其实是值不会改变而已。

        下面给大家说一下解决的办法:

function func() {
   var n = Math.random();
   var m = Math.random();
   return { 
      get_N: function () { return n; },
      get_M: function () { return m; }
   };
}
var o = func();

var n = o.get_N();
var m = o.get_M();

       o接收的是在函数func中return出来的对象,所以调用o就是在调用return出来的对象。

所以我们得到的是对象中的函数通过作用域链查找的上一级的值,然后进行保存,只有作用域链被破坏掉时,才会重新获得数据。

        下面是通过闭包和递归实现的带有缓存的斐波那契数列

        

           闭包的优点是毋容置疑的,减少对于全局变量的污染,在内部形成一个保护数据的私有空间。我们需要得要数据时必须使用一些特殊的方法才可以访问内部的数据,这样可以很大的保护我们存在于闭包中的数据。

        比如我们可以利用沙箱模式来进行处理数据的保护,留下一个特定的方法来可以进行访问,其他方法无效,我们也可以在沙箱中的回调函数中传入document或者dody,window等减少计算机的查询次数。从而减少对于性能的消耗。

(function (w){
   
   function fun() {};
   
   fun.prototype.extend = function (){};
   
   w.I = window.itcast = fun;
   
})(window||document);

        总有一种没写完而又不知道写什么的感觉,大家有什么需要补充的地方评论一下吧,我会及时的补充上去的。递归闭包这些东西,其实都是在操作函数,通过一些特殊的方法使函数可以更方便我们的使用


© 著作权归作者所有

梦在风中
粉丝 26
博文 21
码字总数 17901
作品 0
海淀
程序员
私信 提问
加载中

评论(6)

梦在风中
梦在风中 博主

引用来自“pseudo”的评论

递归消耗的不是性能,是内存,每次递归会在调用栈上创建栈帧,所以调用层次过多会把栈撑爆
递归是有内存的问题,以前不太懂现在学到了,谢谢。但性能的消耗也是存在的,那么递归的性能消耗就是因为在栈上的新建函数数据增多,从而导致性能降低,性能的消耗只是其中的一部分损耗,对吧
pseudo
pseudo
递归消耗的不是性能,是内存,每次递归会在调用栈上创建栈帧,所以调用层次过多会把栈撑爆
2006
2006
学习下,不懂
梦在风中
梦在风中 博主

引用来自“若水191”的评论

对初学者来说,还是没有说清楚什么事闭包
其实闭包就是被函数分割的作用域,使我们无法使用正常的方法获得函数(闭包)内的数据,这个东西就是闭包。
若水191
若水191
对初学者来说,还是没有说清楚什么事闭包
Loveni
Loveni
学习一下
Groovy 中的funtion 和 Closure

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Allocator/article/details/84860885 文章目录 背景 使用gradle 构建的项目中会使用groovy语言来完成项目构建...

Allocator
2018/12/10
0
0
Go语言学习笔记(练习) - 斐波那契数列

斐波纳契数列,又称黄金分割数列,指的是这样一个数列:1、1、2、3、5、8、13、21、……在数学上,斐波纳契数列以如下被以递归的方法定义:F0=0,F1=1,Fn=F(n-1)+F(n-2)(n>=2,n∈N*) 递归...

恐怖幻觉
2013/05/08
2.1K
3
你真的理解【函数式编程】吗?

本文来自作者 李龙生 在 GitChat 上分享「你真的理解函数式编程吗?」,「阅读原文」查看交流实录 「文末高能」 编辑 | 克拉克 前言 现在机器学习、人工智能的发展趋势如火如萘,很多培训班也...

gitchat
2017/11/28
0
0
PHP常用函数篇

PHP常用函数篇 1.为什么要使用函数? 除了内建的PHP函数,我们可以创建我们自己的函数。 函数是可以在程序中重复使用的语句块。 使代码逻辑更清晰 避免过多的全局变量 封装后避免相同逻辑重复...

Besmall
2017/11/01
0
0
匿名函数和闭包规避xdebug限制的函数递归深度限制

PHP版本5.6 先来个简单的用递归求和,代码如下: function add($n){ if($n === 1)return 1; return add($n - 1);}echo add(256); 运行时报错: Maximum function nesting level of '256' rea......

chenzy526
2017/03/15
0
0

没有更多内容

加载失败,请刷新页面

加载更多

32位与64位Linux系统下各类型长度对比

64 位的优点:64 位的应用程序可以直接访问 4EB 的内存和文件大小最大达到4 EB(2 的 63 次幂);可以访问大型数据库。本文介绍的是64位下C语言开发程序注意事项。 1. 32 位和 64 位C数据类型...

mskk
7分钟前
1
0
Vue 实现点击空白处隐藏某节点(三种方式:指令、普通、遮罩)

在项目中往往会有这样的需求: 弹出框(或Popover)在 show 后,点击空白处可以将其 hide。 针对此需求,整理了三种实现方式,大家按实际情况选择。 当然,我们做项目肯定会用到 UI 框架,常...

张兴华ZHero
13分钟前
2
0
SpringBoot激活profiles你知道几种方式?

多环境是最常见的配置隔离方式之一,可以根据不同的运行环境提供不同的配置信息来应对不同的业务场景,在SpringBoot内支持了多种配置隔离的方式,可以激活单个或者多个配置文件。 激活Profi...

恒宇少年
15分钟前
3
0
PDF修改文字的方法有哪些?怎么修改PDF文件中的文字

PDF修改文字一直以来都是一个难以解决的问题,很多的办公族在办公的时候会有修改PDF文件中的文字的需要,可是PDF文件一般是不能进行编辑和修改的,难道就没有什么办法解决这个问题了嘛?不要...

趣味办公社
18分钟前
2
0
企业组织中采用服务网格的挑战

作者:Christian Posta 译者:罗广明 原文:https://blog.christianposta.com/challenges-of-adopting-service-mesh-in-enterprise-organizations/ 编者按 本文作者介绍了企业组织采用服务网...

jimmysong
27分钟前
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部