要想了解闭包,你必须对JavaScript的作用域有一定的了解。我们都知道JavaScript的变量是否可以在当前作用域被访问,主要由它的作用域来决定!
函数作用域可以访问该函数作用域的变量,以及它父级直至全局变量,但是非它作用域内或者乃至它父级甚至全局作用域都无法访问它作用域内的变量
function parent(){
var a=0;
function son(){
console.log(a)
}
}
这就是上边描述的,函数son是函数parent的子作用域,它需要a但是自己没有,它就会往上级作用域查找,直到查找到全局作用于为止;现在parent中有a,所以它可以从parent访问到a变量并打印出来;
这有没有对你想要在其他地方使用a变量有所启发呢?我们都知道,函数内可以return,那么我们可不可以return一个函数出来作为访问a变量的媒介呢?答案是肯定的。
function parent(){
var a=0;
function son(){
console.log(a)
}
return son
}
var bar=parent();
bar();//0
可能你还是觉得很迷茫,那我直接renturn一个a出来不行么?那当然可以,但是若是你需要计算a的值,且保留你计算后的值呢?如果你单纯return一个a出来,你对他进行计算,但是你每次获取a的时候它还是0;
function parent(){
var a=0;
function son(){
console.log(++a)
}
return son
}
var bar=parent();
bar();//1
bar();//2
bar();//3
这就是闭包了。函数嵌套函数时,内层函数引用了外层函数作用域下的变量,并且在外层函数作用域之外执行,这时就产生了闭包。
闭包的作用:
- 访问函数内部的变量
- 由于它的特殊结构,被引用的变量会一直存在内存中
使用闭包需要注意:
- 由于它的变量会一直存在内存中,很可能造成性能问题,所以不可滥用闭包,如果确定无需使用,注意及时销毁
- 由于他可以访问函数内部的变量,所以不要随意修改内部变量的值
我们来做下练习吧。
var a=0;
var obj={
a:1,
bar:function(){
return function(){
console.log(this.a)
}
}
}
var fun=obj.bar();
fun(); // 0
var a=0;
var obj={
a:1,
bar:function(){
var _this=this
return function(){
console.log(_this.a)
}
}
}
var fun=obj.bar();
fun(); // 1
这道题不仅有闭包的知识,你还需要掌握一定this相关知识。函数中的this,在哪里调用,this就指向谁!