一直想把闭包相关的东西整理出来,这篇文章算是闭包相关知识的最终版。
主要分下面几个大的方面:
一、定义及运行
二、特性
三、内存泄露和监控
四、应用
下面详细说下。
一、定义及运行
下面是在百度的时候,做的一次相关分享,可以不妨扫一扫这个ppt,在ppt后,我再提取关键信息。
我再抽取一下关键的信息:
对于闭包的定义很多书籍都很模糊,个人认为比较准确的定义——
闭包是函数的代码在运行过程中的一个动态环境
函数和闭包要有非常清晰的对比——
一个函数只是一段静态的代码、脚本文本,因此它是一个代码书写时,以及编译期的、静态的概念;而闭包则是函数的代码在运行过程中的一个动态环境,是一个运行期的、动态的概念。
闭包作为与函数成对的数据,在函数执行过程中处于激活(即可访问)状态(通俗来讲,就是当执行到函数的某一条语句的时候,哪些对象能够被使用)。
还有一点,就是闭包的实现方式——
JavaScript使用作用域链来实现闭包,作用域链由执行环境维护,JavaScript中所有的标识符都是通过作用域链来查找值的。
二、特性
闭包最为核心的特性便是保存状态,源于活动对象(VO)中所有的变量均置于内存之中,相对而言,激活对象(AO)中的所有变量,在函数执行完成之后,将被垃圾回收器处理。
再具体的东西,在此就不细说了,主要理解了闭包的定义自然就理解它的这个特性。
三、内存泄露及监控
这点,我做的不够充分。先引入几篇文章——
JavaScript Memory Leaks(对应的中文翻译:JavaScript内存泄露):这篇文章主要讲解JavaScript导致内存泄露的几个原因,其中一条便是闭包的使用。
JavaScript内存分析:这篇文章主要讲解如何使用chrome的开发者工具进行内存的分析
这个是司徒正美推荐的一个内存泄露分析的工具——javascript 内存泄露工具使用,在这儿也推荐推荐。
四、应用
这里优先推荐Barret Lee的文章——JS闭包的用途,在这儿重点强调一下:
1. 匿名自执行函数:或者可以理解为,避免污染全局变量
2. 缓存:源于闭包的核心特性便是保存状态,应用此特性便可对需要的变量进行缓存
3. 实现封装:同样可以使用闭包保存状态的特性,充当一个作用域块,将块里面的属性变量至于内存之中来实现封装
4. 闭包的另一个重要用途是实现面向对象中的对象,传统的对象语言都提供类的模板机制:原理同上
总之,这些均是基于闭包的保存状态特性来实现。
五、总结
OK,闭包的话题一直缠绕前端JavaScript理论中的明星话题,并不是一朝一夕就可以理解透彻的,希望看到的同学,多在实践当中思考闭包的种种。