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

  首先要了解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. tornado之用户验证装饰器

    authenticated装饰器 为了使用Tornado的认证功能,我们需要对登录用户标记具体的处理函数.我们可以使用@tornado.web.authenticated装饰器完成它.当我们使用这个装 ...

  2. DRF 商城项目 - 用户( 登录, 注册,登出,个人中心 ) 逻辑梳理

    用户登录 自定义用户登录字段处理 用户的登录时通过 手机号也可以进行登录 需要重写登录验证逻辑 from django.contrib.auth.backends import ModelBacken ...

  3. spring 中的设计模式

    https://mp.weixin.qq.com/s?__biz=MzU0MDEwMjgwNA==&mid=2247485205&idx=1&sn=63455d2313776d ...

  4. Linux 配置代理

    在我们账号的home那有一个.bashrc文件,用来设置一些开机运行的bash命令 cd ~ ls -a vi .bashrc 我们可以在这里添加代理 export http_proxy=" ...

  5. Helm包管理工具(简介、安装、方法)

    认识Helm 每次我们要部署一个应用都需要写一个配置清单(维护一套yaml文件),但是每个环境又不一样.部署一套新的环境成本是真的很高.如果我们能够使用类似于yum的工具来安装我们的应用的话那就太好了 ...

  6. docke 基本安装使用

    特性 容器 虚拟机 启动 秒级 分钟级 硬盘使用 一般为 MB 一般为 GB 性能 接近原生 弱 系统支持量 单机支持上千个容器 一般几十个 容器三大基本概念 镜像 image 容器 containe ...

  7. 字符串join函数跟+号测试

    字符串join函数for循环+区别: 原因是这样的,字符串是不可变对象,当用操作符+连接字符串的时候,每执行一次+都会申请一块新的内存,然后复制上一个+操作的结果和本次操作的右操作符到这块内存空间,因 ...

  8. 半导体知识:蚀刻(Etch)工艺讲解

    本文转载自微信公众号 - 半导体行业观察  , https://mp.weixin.qq.com/s/F3LXiub6n4iYsQDqDH9K_g

  9. mongodb增加新字段报错解决方法

    今天想在项目的一个集合里增加一个新字段 db.article.update({},{$set:{status:0}},{multi:true}) multi : 可选,mongodb 默认是false ...

  10. jenkins启动

    1.已安装JDK,因为jenkins是一款基于java的持续集成工具 2.已配置tomcat,并安装maven 3.下载一个jenkins的war包,放在tomcat/webapps目录下 4.cmd ...