再玩儿一次——深入理解闭包

一直想把闭包相关的东西整理出来,这篇文章算是闭包相关知识的最终版。

 

主要分下面几个大的方面:

一、定义及运行
二、特性
三、内存泄露和监控
四、应用

 

下面详细说下。

 

一、定义及运行

下面是在百度的时候,做的一次相关分享,可以不妨扫一扫这个ppt,在ppt后,我再提取关键信息。

 

 

我再抽取一下关键的信息:

对于闭包的定义很多书籍都很模糊,个人认为比较准确的定义——

闭包是函数的代码在运行过程中的一个动态环境

函数和闭包要有非常清晰的对比——

一个函数只是一段静态的代码、脚本文本,因此它是一个代码书写时,以及编译期的、静态的概念;而闭包则是函数的代码在运行过程中的一个动态环境,是一个运行期的、动态的概念。

闭包作为与函数成对的数据,在函数执行过程中处于激活(即可访问)状态(通俗来讲,就是当执行到函数的某一条语句的时候,哪些对象能够被使用)。

还有一点,就是闭包的实现方式——

JavaScript使用作用域链来实现闭包,作用域链由执行环境维护,JavaScript中所有的标识符都是通过作用域链来查找值的。

 

二、特性

闭包最为核心的特性便是保存状态,源于活动对象(VO)中所有的变量均置于内存之中,相对而言,激活对象(AO)中的所有变量,在函数执行完成之后,将被垃圾回收器处理。

再具体的东西,在此就不细说了,主要理解了闭包的定义自然就理解它的这个特性。

 

三、内存泄露及监控

这点,我做的不够充分。先引入几篇文章——

JavaScript Memory Leaks(对应的中文翻译:JavaScript内存泄露):这篇文章主要讲解JavaScript导致内存泄露的几个原因,其中一条便是闭包的使用。

JavaScript内存分析:这篇文章主要讲解如何使用chrome的开发者工具进行内存的分析

这个是司徒正美推荐的一个内存泄露分析的工具——javascript 内存泄露工具使用,在这儿也推荐推荐。

 

四、应用

这里优先推荐Barret Lee的文章——JS闭包的用途,在这儿重点强调一下:

1. 匿名自执行函数:或者可以理解为,避免污染全局变量
2. 缓存:源于闭包的核心特性便是保存状态,应用此特性便可对需要的变量进行缓存
3. 实现封装:同样可以使用闭包保存状态的特性,充当一个作用域块,将块里面的属性变量至于内存之中来实现封装
4. 闭包的另一个重要用途是实现面向对象中的对象,传统的对象语言都提供类的模板机制:原理同上

总之,这些均是基于闭包的保存状态特性来实现。

 

五、总结

OK,闭包的话题一直缠绕前端JavaScript理论中的明星话题,并不是一朝一夕就可以理解透彻的,希望看到的同学,多在实践当中思考闭包的种种。

 

posted @ 2016-03-17 14:05  金广国  阅读(1057)  评论(0编辑  收藏  举报