什么是闭包
如果内层函数使用了外层函数中定义的局部变量,并且外层函数的返回值是内层函数的引用,就构成了闭包。
闭包可以让我们在一个内层函数中访问到外层函数的作用域。
在js中,每当创建一个函数,闭包就会在函数创建的同时被创建出来,作为函数内部与外部连接起来的一个桥梁。
下面是一个计数器(闭包)的例子:
1>在初始化c的时候,add()方法执行一次,但是没有执行plus,最终返回plus函数。
2>第一次调用c(),闭包函数plus()第一次执行,counter+1,值为1.
3>第二次调用c(),闭包函数plus()第二次执行,counter再次+1,值为2
//实现计数器
function add(){
var counter = 0;
function plus(){
counter += 1;
console.log(counter);
}
//这里的返回值不加()
return plus;
}
var c = add(); //这里plus没有执行
c();
c();
//最终输出1 2
还有当频繁调用具有相同参数的函数时,使用闭包可以进行重用。
比如我们计算长方形的面积,一般的写法如下:
function area(width,height){
return width*height;
}
area(10,2);
area(10,3);
但是当我们多次使用width=10来计算时,可以使用闭包来避免相同参数的频繁调用:
//使用闭包求长方形面积
function solve(width){
function area(height){
return width*height;
}
return area;
}
var a = solve(10);
console.log(a(2)); //20
console.log(a(3)); //30
闭包的作用
闭包常常用来间接访问一个变量,或者隐藏变量。(全局变量能通过闭包实现局部私有)
在js中,没有声明私有变量的方法,这时可以通过闭包来完成。
还是计数器的例子,我们声明两个计数器c和d:
其中c和d是维护他们各自独立性的,每次调用其中一个计数器时,会改变这个闭包的词法环境,但是不会影响另一个闭包中的变量。
//实现计数器
function add(){
var counter = 0;
function plus(){
counter += 1;
console.log(counter);
}
//这里的返回值不加()
return plus;
}
var c = add(); //这里plus没有执行
c(); //1
c(); //2
var d = add();
d(); //1 c计数器不会改变d计数器
闭包主要用在计数器、延迟调用、回调等。
核心思想是创建私有变量、延迟变量的生命周期。