理解Javascript中的Closures即闭包
介绍Javascript中闭包的概念。
一、什么是Closures 即“闭包”?
Closures被翻译为计算机术语即为“闭包”wiki上的定义:
In computer science, a closure is a first-class function with free variables that are bound in the lexical environment.
这句话其实说了两层意思,所谓闭包,就是需要执行的程序代码与其执行的环境的集合。从这个层面上来说,所有的Javascript函数都是计算机科学意义上的“闭包”。等等......为什么你说的和我平常看的文章不一样啊?可能有人要这么问了,不错,如果我们讨论上述所说的“闭包”,那也没什么可说的了。今天我要说的是这么一种情况:一个函数的返回值是它的内部函数。
二、什么是call object?
Javascript中函数执行时。首先,解释器会根据函数定义时的作用域,为函数在全局作用域中,创建一个函数运行时环境。其次,解释器初始化一个call object,并把这个call Object放在全局作用域的最前端,call object有个arguments属性,这个属性指向该函数的Arguments Object。再次,解释器会为call object定义上该函数内部用Var关键字声明的变量,以及其它被该函数引用的变量。注意:以上论述阐述了一个事实,函数内局部变量将覆盖全局变量,下面代码将证明这一事实。
要真正理解“闭包”,就必须先理解上述原理。
三、闭包技术的原理。
先看一个使用“闭包”特性的简单例子
当getx执行完毕后,getx的call object并未从全局作用域中移除,因为返回的“闭包”增加了对getx的call object的引用,这听起来有点儿抽象。我再解释一下,在Javascript中,比方A函数执行时,A的call object就根据A定义的上下文环境被创建。A函数返回后,A的call object引用A,同时A引用A的call object,再没有第三者,这时候,A和A的call object就可以被垃圾回收器回收。当A中有内部函数B,并且B在A的内部执行时,事情是这样的,A函数执行时,A的call object就根据A定义的上下文环境被创建。A引用A的call object,执行到B时,B引用A的call object,A函数返回后,只有B引用了A的call object,同时A的call object也只引用了B。这时候事情就结束了,等待内存被回收。上述代码的关键之处在于,B并没有被执行,而是作为A的返回值,B对A的call object的引用增加了一次,因此A的call object在A执行完毕以后并没有被消失,所有的内部变量,参数,在A执行完毕之后依然在内存当中。这就是“闭包”技术的关键所在。
四、闭包技术的应用。
闭包技术通常用来模拟私有变量
没有评论:
发表评论