什么是闭包阮一峰老师说的很清楚了,定义在一个函数内部的函数,在本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁

  首先要了解Javascript的变量作用域:全局变量局部变量。全局嘛,就是共享,任何一个函数内部可以直接读取全局变量;局部嘛,就是私有,不暴露在外的。如何判断该变量是全局还是局部,函数内部看它有没有var进行声明。没有var声明的变量,实际是个全局变量,别被骗咯!

傲娇的小眼神(别被骗咯)

  Javascript语言特有的"链式作用域"结构(chain scope),子对象会一级一级地向上寻找所有父对象的变量。所以,父对象的所有变量,对子对象都是可见的,反之则不成立。既然子对象可以读取父对象的变量,那我们想获取一个对象(假设为f1)里面的变量,给f1创建一个子对象(假设为f2),并将子对象return出去,不就可以在外部访问到这个对象(f1)的私有变量。f2就是闭包,没错,它就是闭包。不多说,代码如图:

f2即为闭包

  那么问题来了,你说闭包是为了获取一个函数内部的私有数据而创建的,那我直接将一个想要获取的数据return出去,外部不一样可以获取嘛,不多说,看权威的jquery源码:

我非要return

外部访问数据

  也有人说闭包可以防止全局变量污染,什么是全局变量污染?当多人一起开发一个大型项目的时候,每个人负责一块,其中定义的全局变量可能会存在命名冲突,当项目进行整合的时候起冲突的全局变量会被覆盖,这应该很好理解。闭包的应用将变量私有化,可以起到防止变量全局污染的作用,外部同时也可以访问到私有化的变量。解决全局变量污染的问题,可以结合js模块化开发思维,如下图:

js模块化一

js模块化二(闭包)

  两者的区别在图片中已经阐明了,可以自行试一试。闭包还有一个比较大的用处,相信你们都知道,让这些变量的值始终保持在内存中。所以注意的一点就是:由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。(阮一峰老师原话,偷点懒0.0)。

  这句话不知道你们能否了解,我简单阐述下我的想法,一定要认真看完哈!首先全局变量和局部变量生命周期是不同的,全局变量存放在一个区域内,具有全局作用域;局部变量放在堆栈中,由编译器自动分配释放,存放函数的参数值,局部变量的值等,只有局部作用域,在程序运行期间不是一直存在,而是只在函数执行期间存在,函数的一次调用执行结束后,变量被撤销,其所占用的内存也被收回(GC)垃圾回收机制(GC)原理:垃圾收集器会按照固定的时间间隔,周期性找出不再使用的变量,然后释放其占用的内存。不再使用的变量也就是生命周期结束的变量,是局部变量,局部变量只在函数的执行过程中存在,当函数运行结束,没有其他引用(闭包),那么该变量会被标记回收。全局变量的生命周期直至浏览器卸载页面才会结束,也就是说全局变量不会被当成垃圾回收。当一个局部变量存在引用(闭包),该变量也不会被当成垃圾回收,始终存在于内存中。

  闭包这种将变量始终存储,大家知道有什么好处么?可以仔细研究想想,再深剖会发现,闭包在性能优化方面优势很明显,对比下return,如图所示:

闭包与return对比

  如上代码,通过闭包,在外部对数据进行操作时候,红框内代码不会再一次执行,也就是f1里面劈里啪啦一顿猛如虎的操作之后获得的n,存储到内存中后,外部操作实际上是对存储在内存上的数据进行了操作。相比return,如果外部想获得内部的私有数据再操作,那内部的程序在外部每获取一次就需要跑一次,这无形中消耗着电脑的性能,所以我觉得,闭包的合理使用,是可以降低电脑性能的消耗起到一定的优化性能的作用。不合理的使用闭包会导致内存泄漏。

  好了,谢谢你这么帅,还能看完我的分享,希望对你有所帮助(辛辛苦苦写了那么多,兄dei,点个赞再走吧),送你一朵❀。

关于javascript闭包(Closure)和return之间的暧昧关系的更多相关文章

  1. JavaScript闭包(Closure)

    JavaScript闭包(Closure) 本文收集了多本书里对JavaScript闭包(Closure)的解释,或许会对理解闭包有一定帮助. <你不知道的JavsScript> Java ...

  2. 深入理解JavaScript闭包(closure)

    最近在网上查阅了不少javascript闭包(closure)相关的资料,写的大多是非常的学术和专业.对于初学者来说别说理解闭包了,就连文字叙述都很难看懂.撰写此文的目的就是用最通俗的文字揭开Java ...

  3. [转载]学习Javascript闭包(Closure)

    学习Javascript闭包(Closure)     源地址: http://www.ruanyifeng.com/blog/2009/08/learning_javascript_closures ...

  4. javascript 闭包(closure)

    <script type="text/javascript">    //闭包(closure):内层函数可以引用存在于包围它的函数内的变量,即使外层函数的执行已经结束 ...

  5. JavaScript闭包(closure)入门: 拿"开发部"和"技术牛"举个例子

    虽然只是一小段菜鸟的学习笔记 , 不过还是希望看到的高手看到不足的时候帮忙指点~ 一:代码和执行过程 /** * http://blog.csdn.net/ruantao1989 * ==>Ju ...

  6. JavaScript原型链和instanceof运算符的暧昧关系

    时间回到两个月前,简单地理了理原型链.prototype以及__proto__之间的乱七八糟的关系,同时也简单了解了下typeof和instanceof两个运算符,但是,anyway,试试以下两题: ...

  7. JavaScript闭包(二)——作用

    一.延迟调用 当在一段代码中使用 setTimeout 时,要将一个函数的引用作为它的第一个参数,而将以毫秒表示的时间值作为第二个参数. 但是,传递函数引用的同时无法为计划执行的函数提供参数.可以在代 ...

  8. JavaScript闭包(一)——实现

    闭包的官方的解释是:一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分. 通俗点的说法是: 从理论角度:所有的函数.因为它们都在创建的时候就将上层上下文 ...

  9. JavaScript闭包——实现

    闭包的官方的解释是:一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分. 通俗点的说法是: 从理论角度:所有的函数.因为它们都在创建的时候就将上层上下文 ...

随机推荐

  1. 自动化测试框架【windows版】:JMeter + Ant + Jenkins

    前提条件:windows安装了jmeter.ant.jenkins 安装方法参考汇总目录中对应的博文 截图看不清的,可以调大浏览器倍数看 jenkins驱动ant执行,ant驱动jmeter执行 an ...

  2. HEOI2013SAO

    题目描述 给定一个\(DAG\),问这个\(DAG\)有多少种拓扑序. 题解 我们首先需要设计一个能够比较好的转移的状态. 我们可以设\(dp[i][j]\)表示第i个点在当前\(dp\)的子图中拓扑 ...

  3. mysql优化 | 存储引擎,建表,索引,sql的优化建议

    个人对于选择存储引擎,建表,建索引,sql优化的一些总结,给读者提供一些参考意见 推荐访问我的个人网站,排版更好看: https://chenmingyu.top/mysql-optimize/ 存储 ...

  4. Tomcat 配置文件 server.xml

    Tomcat隶属于Apache基金会,是开源的轻量级Web应用服务器,使用非常广泛.server.xml是Tomcat中最重要的配置文件,server.xml的每一个元素都对应了Tomcat中的一个组 ...

  5. 我的mybatis从oracle迁移转换mysql的差异【原】

    仅此作为笔记 分页差异 oracle <select id="select" parameterClass="java.util.Map" resultC ...

  6. [源码分析]Java1.8中StringJoiner的使用以及源码分析

    [源码分析]StringJoiner的使用以及源码分析 StringJoiner是Java里1.8新增的类, 或许有一部分人没有接触过. 所以本文将从使用例子入手, 分析StringJoiner的源码 ...

  7. BeanUtils 日期转换(本地格式yyyy-MM-dd)转换成date

    1.BeanUtils工具的使用 1)beanUtils 可以便于对javaBean的属性进行赋值. 2)beanUtils 可以便于对javaBean的对象进行赋值. 3)beanUtils可以将一 ...

  8. 使用onblur+alert+focus导致的死循环解决

    <input type="text" id="loginName" onblur="checkLoginName()"/> fu ...

  9. opencv中imgshow图像显示为灰色

    1.图像数据类型是否正确 2.图像是否存在 3.在imgshow()语句下添加watkey();

  10. MySQL学习11 - MySQL创建用户和授权

    权限管理 权限管理 我们知道我们的最高权限管理者是root用户,它拥有着最高的权限操作.包括select.update.delete.update.grant等操作.那么一般情况在公司之后DBA工程师 ...