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


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 相关文章推荐
可缩放Reloaded-一个针对可缩放元素的复用组件
Mar 10 Javascript
Javascript 网页黑白效果实现代码(兼容IE/FF等)
Apr 23 Javascript
js有关元素内容操作小结
Dec 20 Javascript
JS Map 和 List 的简单实现代码
Jul 08 Javascript
按Enter键触发事件的jquery方法实现代码
Feb 17 Javascript
js实现touch移动触屏滑动事件
Apr 17 Javascript
JavaScript 基础函数_深入剖析变量和作用域
May 18 Javascript
javaScript事件学习小结(四)event的公共成员(属性和方法)
Jun 09 Javascript
javascript获取指定区间范围随机数的方法
Sep 08 Javascript
从零开始实现Vue简单的Toast插件
Dec 03 Javascript
微信小程序使用map组件实现检索(定位位置)周边的POI功能示例
Jan 23 Javascript
基于vue实现探探滑动组件功能
May 29 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的cms
2010/12/19 PHP
php array_push()数组函数:将一个或多个单元压入数组的末尾(入栈)
2011/07/12 PHP
php项目中百度 UEditor 简单安装调试和调用
2015/07/15 PHP
php实现微信扫码自动登陆与注册功能
2016/09/22 PHP
php ajax confirm 删除实例详解
2019/03/06 PHP
不错的新闻标题颜色效果
2006/12/10 Javascript
ExtJS 2.0实用简明教程之应用ExtJS
2009/04/29 Javascript
js对象与打印对象分析比较
2013/04/23 Javascript
jQuery cdn使用介绍
2013/05/08 Javascript
js获取location.href的参数实例代码
2013/08/02 Javascript
网站404页面3秒后跳到首页的实例代码
2013/08/16 Javascript
jQuery取得设置清空select选择的文本与值
2014/07/08 Javascript
详解JavaScript的回调函数
2015/11/20 Javascript
Bootstrap文件上传组件之bootstrap fileinput
2016/11/25 Javascript
Angular.JS去掉访问路径URL中的#号详解
2017/03/30 Javascript
利用JS测试目标网站的打开响应速度
2017/12/01 Javascript
JS动画定时器知识总结
2018/03/23 Javascript
修改npm全局安装模式的路径方法
2018/05/15 Javascript
[01:44]剑指西雅图 展望TI之CIS战队专访
2014/06/25 DOTA
[16:21]教你分分钟做大人:圣堂刺客
2014/12/03 DOTA
使用Python判断质数(素数)的简单方法讲解
2016/05/05 Python
使用Python脚本实现批量网站存活检测遇到问题及解决方法
2016/10/11 Python
python打包压缩、读取指定目录下的指定类型文件
2018/04/12 Python
Python定时发送消息的脚本:每天跟你女朋友说晚安
2018/10/21 Python
python 输出所有大小写字母的方法
2019/01/02 Python
Django实现学员管理系统
2019/02/26 Python
TensorFlow索引与切片的实现方法
2019/11/20 Python
matplotlib subplot绘制多个子图的方法示例
2020/07/28 Python
HTML5 Canvas的事件处理介绍
2015/04/24 HTML / CSS
澳大利亚在线奢侈品时尚零售平台:Azura Runway
2021/01/13 全球购物
校园广播稿精选
2014/10/01 职场文书
高三语文复习计划
2015/01/19 职场文书
2015年乡镇科普工作总结
2015/05/13 职场文书
退休欢送会主持词
2015/07/01 职场文书
浅谈redis缓存在项目中的使用
2021/05/20 Redis
Python预测分词的实现
2021/06/18 Python