什么是闭包?
wiki的解释:
在计算机科学中,闭包是词法闭包的简称,是引用了自由变量的函数。这个被引用的自由变量将和这个函数一同存在,即使
已经离开了创造他的环境也不例外。所以,有另一种说法认为闭包是由函数和与其相关的引用环境组合而成的实体。
举个例子:
function a(){
var x=10;
var y=20;
function b(){
console.log(x);//Output 10
}
b();
}
a();
根据我之前讲的 b函数在预处理阶段会被默认添加一个[[scope]]成员属性 他指向创建函数时的词法环境,b在预处理阶段会被扫描其函数体,若其出现引用了外部变量,将会捕获外部词法环境的变量形成一个闭包并将其添加上。(父函数没有就会继续查找父的父,直到window)。以上所讲的在现有的调试工具时观察不到的
而什么叫做即使已经离开了创造他的环境也不例外呢?举个鲜明的例子
function a(){
var x=10;
var y=20;
return function b(){
console.log(x);
}
b();
}
var result = a();
result();//Output 10
闭包的好处:
1.减少全局变量使用
如果我想实现每调用一次func()函数x的值都会+1,那么正常的方式都会添加一个全局变量,这样会可能造成全局变量污染(全局变量是恶魔!!)
var x=0;
function func(){
x++;
console.log(x);
}
func();
func();
那我们该如何通过闭包来修改我们的代码呢
function func(){
var x=0;
return function func1(){
x++;
console.log(x)
}
}
var result =func();
result();
result();
这样就避免了全局变量被重复调用的风险,并隐藏了x这个变量
2.减少传递给函数的参数数量
function calfunc(base)
{
return function(max){
for(var i=1;i<=max;i++){
base+=i;
}
return base;
}
}
var add = calfunc(2);//base = 2
console.log(add(3));//Output 8
3.封装
(function(){
var x;
function setx(val){
x=val;
}
function disx(){
return x;
}
window.sx=setx;//将setx这个函数赋值给全局变量sx,此时该函数与x已经形成了一个闭包
window.dx=disx;//将disx这个函数赋值给全局变量dx,此时该函数与x已经形成了一个闭包
})()
sx(2);
console.log(dx());//Output 2