作用域与闭包的基本概念
If you can't explain it to a six-year-old, you really don't understand it yourself.
闭包(closure)是JavaScript语言的一个难点,也是JavaScript的一个特色,很多高级的应用都要依靠闭包来实现。
作用域
在js中,函数会形成函数作用域,在函数内部可以直接访问全局变量
varstr="zs";
functionfn(){
console.log(str);//访问全局变量
}
fn();//zs
在函数外部却无法访问函数内部的变量
functionfn(){
varstr="zs";
}
fn();
console.log(str);//报错 str is not defined
问题:我怎么才能获取到函数内部的变量?
作用域链
在函数内部有一个函数,那么函数内部的函数是可以访问到外部函数的变量的。
解决方法:
functionfn(){
varstr="zs";
functionf2(){
console.log(str);
}
f2();
}
fn();
在上述代码中,fn中定义的所有变量,对于f2函数都来都是可以访问的。但是现在f2在函数的内部,我们如何在外部访问到f2这个函数呢?
functionfn(){
varstr="zs";
functionf2(){
console.log(str);
}
returnf2;
}
varresult=fn();
result();// "zs"
闭包的概念
上面代码中的f2就是闭包,闭包就是能够读取到其他函数内部变量的函数。因此我们可以把闭包理解为定义在函数内部的函数;
闭包是函数内部与外部连接起来的桥梁。
闭包的应用
计数器
需求:统计一个函数的调用次数
varcount=0;
functionfn(){
count++;
console.log("我被调用了,调用次数是"+count);
}
fn();
fn();
fn();
缺点:count是全局变量,不安全。
使用闭包解决这个问题!!!!
functionouter(){
varcount=0;
functionadd(){
count++;
console.log("当前count"+count);
}
returnadd;
}
varresult=outer();
result();
私有变量
使用闭包实现私有变量的读取和设置
functionouter(){
varnum=10;
functionset_num(n){
num=n;
}
functionget_num(){
returnnum;
}
return{
set_num:set_num,
get_num:get_num
}
}
varobj=outer();
obj.set_num(2000);
console.log(obj.get_num());