闭包,官方解释:一个拥有许多变量和绑定了这些变量的环境的表达式,通常是一个函数,因而这些变量也是该表达式的一部分。
抽象,难以理解,再普通一点来说,就是函数返回函数。
找一个最简单的例子:
function a(i) { function b(j) { return i+j; } return b; } var add = a(1); alert(add(5));
执行的结果是弹出6;
变量add中存放的是函数b,因为再函数a中返回值为b,并且b没有加括号。
add的内容是:
function b(j) { return i+j; }
原始的代码中先定义了一个a函数,在a函数中又定义了一个b函数,并且在b函数中使用了a函数中的i这个参数,然后调用了a(1),让add引用了a函数中返回的内嵌函数b,a(1)的功能是将一个数字加1,这这时又调用了add(5),相当于已经绑定了变量i,并且将i的值赋值为了1,之后调用了add(5),即将变量j赋值为5,执行之后就是1+5,所以add(5)的结果就是6.
所以Js中闭包的产生条件:
- 嵌入函数使用了外部函数的局部变量;
- 外部函数引用了内嵌函数;
上面的例子中,嵌入函数b使用了局部变量i,外部函数a引用了内嵌函数b;
但是,如果内嵌函数中没有使用外部函数的局部变量,那么就没有必要绑定定义时环境中的变量,浏览器也是这样实现的,再者,如果外部变量没有引用内嵌函数,则内嵌函数被垃圾回收,形成的闭包也会无法使用。所以需要看一下闭包实现的原理。
Js闭包中绑定定义时环境中的变量是通过js的函数作用域链实现的,要理解闭包的原理,先要理解js函数的作用域链。因为我自己学的还不是很深,对于闭包的原理理解的也还不够,所以只能写一点简单的用法,和自己的一点理解,这也是参照了一些前辈的经验总结出来的。
另外在Js闭包的应用方面,主要是多用来封装和保存现场。
- 封装是因为闭包绑定的变量只能供自己使用,对外部是隐藏的;
- 保存现场是因为保存的是定义时的变量,可以通过闭包保存定义时的现场,方便后面使用。