让你一句话理解闭包(简单易懂)


Posted in Javascript onJune 03, 2016

接触javascript很久了,每次理解闭包都似是而非,最近在找Web前端的工作,所以需要把基础夯实一下。

本文是参照了joy_lee的博客 闭包 在她这篇博客的基础上以批注的形式力争把我的理解阐述出来,如果有不当之处,欢迎批评指正。

《高级程序设计》上,这样说:当在函数内部定义了其他函数时候,就创建了闭包。闭包有权访问包含函数内部的所有变量。

这句话怎么理解呢?照这句话理解的话,闭包就是一个嵌套函数嘛!嵌套函数对包含它的函数的变量当然可以访问,这是没有问题的。

一般来说,内部函数是能够访问到上一级乃至全局的的变量的,那么就有人这样理解:通过闭包,可以实现外部访问函数局部内的变量。

(如果我们把作用域简单的分个级的话,假设全局作用域作为第一级,其中定义的函数体内部作用域作为第二级,在第二级作用域内嵌套定义的函数体内部作用域作为第三级,....等等,传统意义上,第一级不能访问第二级的变量(这种变量叫做局部变量),第二级不能访问第三级,...,而反过来是可以的,这就是作用域链。本级作用域内找不到再到上一级找,直至第一级全局。而闭包这种机制可以在第一级作用域中通过第三级作用域引用到第二级作用域中的变量,而方法就是在第二级作用域向第一级作用域返回拥有第三级作用域的函数引用。 这个引用才是关键,因为这个引用的存在,相关的第三作用域与第二作用域都成了这个引用运行的上下文,迫使垃圾回收机制GC不能回收这条链上所占用的资源。而如果没有这个引用,则跟一般函数一样,函数运行完资源就会被回收。而我的疑惑也在于此,闭包单指函数中的嵌套函数还是指被第一级引用了的嵌套函数?还是都是?还是说闭包并不是嵌套函数而是嵌套函数被第一级作用域引用时所形成的这种机制?)

function a(){ 
 
   var i=0; 
 
  function b(){ 
 
     alert(++i); 
 
    } 
 
   return b; 
 
 } 
 
 var c = a(); 
 
 c();

即,闭包的作用就是在a执行完并返回后,闭包使得Javascript的垃圾回收机制GC不会收回a所占用的资源,因为a的内部函数b的执行需要依赖a中的变量。

由于闭包的存在使得函数a返回后,a中的i始终存在,这样每次执行c(),i都是自加1后alert出i的值。

那么,如果a不返回函数b,情况就完全不同了。因为a执行完后,b没有被返回给a的外界,只是被a所引用,而此时a也只会被b引用,因此函数a和b互相引用但又不被外界打扰(被外界引用),函数a和b就会被GC回收。

实际上是就是闭包延长变量的生命周期。通常函数的作用域即变量会在函数执行结束后被销毁,但当函数返回一个闭包,只要闭包不被释放,整条作用域链都会占用内存。(闭包延长变量的生命周期,这是指被第一级引用的情况。但如果没有这个引用,闭包还能称其为闭包吗?

说道作用域链:即 函数自己的作用域、上一层的函数的作用域....和全局作用域。访问一个变量时,自己的没有,就一层层往上找,直至全局,若还没有,就报错。

很想吐槽一句,闭包的作用域链是弯的。

PS: 有网友推荐了另一篇文章javascript闭包概念简单解析,是不是权威暂且不提,总算有一个明确的概念:

说了这么多,闭包到底是什么,下面做一下总结:

闭包是一个概念,它描述了函数执行完毕内存释放后,依然内存驻留的一个现象,只要把握这个核心概念,闭包就不难理解了。

以上这篇让你一句话理解闭包(简单易懂)就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
兼容IE和FF的js脚本代码小结(比较常用)
Dec 06 Javascript
jQuery简单实现禁用右键菜单
Mar 10 Javascript
JavaScript模块规范之AMD规范和CMD规范
Oct 27 Javascript
深入理解JavaScript中的call、apply、bind方法的区别
May 30 Javascript
jQuery制作圣诞主题页面 更像是爱情影集
Aug 10 Javascript
angular.js之路由的选择方法
Sep 24 Javascript
使用bootstrapValidator插件进行动态添加表单元素并校验
Sep 28 Javascript
JS实现物体带缓冲的间歇运动效果示例
Dec 22 Javascript
深入理解在JS中通过四种设置事件处理程序的方法
Mar 02 Javascript
实例讲解DataTables固定表格宽度(设置横向滚动条)
Jul 11 Javascript
详解在vue-cli项目中使用mockjs(请求数据删除数据)
Oct 23 Javascript
JavaScript 中的无穷数(Infinity)详解
Feb 13 Javascript
Js类的静态方法与实例方法区分及jQuery拓展的两种方法
Jun 03 #Javascript
JS两个数组比较,删除重复值的巧妙方法(推荐)
Jun 03 #Javascript
JS Array创建及concat()split()slice()的使用方法
Jun 03 #Javascript
浅谈JavaScript的push(),pop(),concat()方法
Jun 03 #Javascript
Jquery中map函数的用法
Jun 03 #Javascript
JavaScript进阶练习及简单实例分析
Jun 03 #Javascript
jQuery EasyUI 入门必看
Jun 03 #Javascript
You might like
检查php文件中是否含有bom的函数
2012/05/31 PHP
简单谈谈PHP面向对象之标识对象
2017/06/27 PHP
Laravel5框架自定义错误页面配置操作示例
2019/04/17 PHP
让人期待的2011年度最佳 jQuery 插件分享
2012/03/16 Javascript
向当前style sheet中插入一个新的style实现方法
2013/04/01 Javascript
基于jQuery实现图片的前进与后退功能
2013/04/24 Javascript
SwfUpload在IE10上不出现上传按钮的解决方法
2013/06/25 Javascript
jQuery中事件对象e的事件冒泡用法示例介绍
2014/04/25 Javascript
php,js,css字符串截取的办法集锦
2014/09/26 Javascript
javascript学习笔记(六)数据类型和JSON格式
2014/10/08 Javascript
基于jQuery实现select下拉选择可输入附源码下载
2016/02/03 Javascript
javascript事件委托的用法及其好处简析
2016/04/04 Javascript
基于JS实现移动端访问PC端页面时跳转到对应的移动端网页
2020/12/24 Javascript
AngularJS基础 ng-model 指令详解及示例代码
2016/08/02 Javascript
手机图片预览插件photoswipe.js使用总结
2016/08/25 Javascript
微信小程序 教程之wxapp视图容器 scroll-view
2016/10/19 Javascript
清除输入框内的空格
2016/12/21 Javascript
javascript实现QQ空间相册展示源码
2017/12/12 Javascript
AngularJS中重新加载当前路由页面的方法
2018/03/09 Javascript
搭建vue开发环境
2018/07/19 Javascript
详解如何给React-Router添加路由页面切换时的过渡动画
2019/04/25 Javascript
vue实现数字动态翻牌的效果(开箱即用)
2019/12/08 Javascript
es5 类与es6中class的区别小结
2020/11/09 Javascript
零基础写python爬虫之使用urllib2组件抓取网页内容
2014/11/04 Python
python urllib urlopen()对象方法/代理的补充说明
2017/06/29 Python
对python过滤器和lambda函数的用法详解
2019/01/21 Python
TensorFlow索引与切片的实现方法
2019/11/20 Python
使用phonegap播放音频的实现方法
2017/03/31 HTML / CSS
使用canvas来完成线性渐变和径向渐变的功能的方法示例
2019/07/25 HTML / CSS
四方通行旅游网:台湾订房、出国旅游
2017/09/20 全球购物
会计与审计专业大专生求职信
2013/10/03 职场文书
党校培训自我鉴定范文
2014/03/20 职场文书
营销总经理岗位职责范本
2014/09/02 职场文书
使用HTML+Css+transform实现3D导航栏的示例代码
2021/03/31 HTML / CSS
Java异常处理try catch的基本用法
2021/12/06 Java/Android
python神经网络 使用Keras构建RNN训练
2022/05/04 Python