1.什么是闭包?
官方解释:闭包是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分。
相信很多朋友对这种解释非常反感,因为看完以后根本不知道它想表达什么。
function f1(){
var n=123;
function f2(){
alert(n);
}
return f2;
}
var result=f1();
result(); // 123
上面代码中f2方法就是闭包。
代码中n是f1方法的局部变量,无法再方法外部获得。因为f2同样在f1方法内部,所以f1的内部所有变量对f2都是可见的,这时只要把f2作为返回值,我们就可以在f1外部读取到f1的局部变量。
注意:f1中局部变量对f2是可见的,但是f2中局部变量对f1则是不可见的。这就是javascript语言的链式作用域(chain scope)。
所以小编理解,闭包就是能够读取其他函数内部变量的函数。由于在Javascript语言中,只有函数内部的子函数才能读取局部变量,因此可以把闭包简单理解成“定义在一个函数内部的函数”。
作用上讲,闭包是将函数内部与函数外部连接起来的一座桥梁。
2.闭包的用途:
闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现。
闭包有两个非常大的用途:
一、就是上面介绍的js闭包(closure)可以让方法内部的局部变量变得可以在方法外部读取;
二、js闭包(closure)可以这些变量值始终保持在内存中。
怎么来理解js闭包(closure)的第二个用途呢?代码是最通用的语言
function f1(){
var n=123;
nAdd=function(){n+=1}
function f2(){
alert(n);
}
return f2;
}
var result=f1();
result(); // 123
nAdd();
result(); // 124
上面代码result()方法执行两次,第一执行n值为123,第二次执行n值为124。这说明f1方法中局部变量n一直保持在内存中。
那么上面现象原因是什么呢?
原因是f1返回值为f2,f2被赋值给变量result,result在内存中导致f2也始终在内存中。同时f2是f1的局部方法,f2在内存中导致f1也始终在内存中。这就导致f1没有在调用结束后被垃圾回收机制(garbage collection)回收。