一、概述
什么是闭包?MDN中第一句话就是
A closure is the combination of a function and the lexical environment within which that function was declared
也就是说closure=function+lexical environment,lexical environment即是function声明的地方,然而这并不容易理解,或者说有点概念化,之后又参考了几篇文章,终于初步理解了闭包。
二、常见闭包
我们通常见到的闭包往往是这样的,例一:
function exam(){
var a=3
function fn(){ //closure
alert(a)
}
fn()
}
也就是说闭包常以函数嵌套的方式出现,但是根据闭包的定义,以下例子也是闭包,例二:
var a=3
function(){ //closure
return a
}
那么为什么我们常见的是第一种嵌套函数样式的闭包呢?原因就在于闭包的用途,我们有时需要隐藏一个变量,但是又不能完全不可引用,这个时候就用到了闭包。
如同例一中的a,在全局环境中本无法直接访问到,但是我们通过闭包,外界环境就可以访问到a,这里exam()的存在事实上只是使a变成了局部变量而已,也就是说,例三:
!function(){
a=3
function fn(){
alert(a)
}
fn()
}()
使用一个立即执行的外层函数实际上可以达到同样的效果。
三、重要特性
闭包有一个重要特性,即是状态的保持,我们知道,普通函数是不会保存状态的,如,例四:
function fn(){
var a=0;
console.log(++a);
}
fn(); //1
fn(); //1
fn(); //1
显然,这里的fn函数无论调用多少次都是输出1,下一个例子,例五:
function fn(){
var a=0;
return function(){ //closure
console.log(++a);
}
}
var aFn=fn();
aFn(); //1
aFn(); //2
aFn(); //3
例五中每调用一次,原来的a就加了1,这就说明原来的fn中return的匿名函数的所处环境被保留了(即使此时fn本身已经被清除了),说明aFn自己保持了他所处环境(lexical environment)的引用。
四、总结
说了这么多我感觉概念性的东西太容易把人绕晕,可能我们经常在使用它的时候反而没那么在意闭包的概念,值得一提的是个人认为闭包的状态保持是一个很有意思的东西。
网友评论