简单理解js闭包
一、闭包
1.闭包的概念
在函数外部访问函数作用域中变量(局部变量)的函数,或者能够读取其他函数内部变量的函数,又或者有权访问另一个函数作用域中的变量的函数.
2.闭包的作用
正常函数执行完毕后,里面声明的变量被垃圾回收处理掉,但是闭包可以让作用域里的变量生命周期延长,在函数执行完之后依旧存在.
- 1.在一个函数的外部,使用函数的内部局部变量
- 2.形成块级作用域
二、知识引导
1.js中函数体内可以直接读取全局变量
代码如下(示例):
let a = 123;
function fun(){
console.log(a);
}
fun();
2.js中外部变量不能直接读取到函数体内的变量
代码如下(示例):
function fun(){
let a = 123;
}
console.log(a);//报错
3.获取函数体内的值
代码如下(示例):
function fun1(){
let a = 123;
function fun2(){
console.log(a);
}
fun2();//通过调用;
}
fun1();
4.获取函数体内的值的困境
代码如下(示例):
function fun1(){
let a = 123;
function fun2(){
a++;
console.log(a);
}
fun2();
}
fun1();//124
fun1();//124
fun1();//124
//值不能一直递增了,怎么办呢?
5.获取函数体内值改进版
代码如下(示例):
function fun1(){
let a = 123;
function fun2(){
console.log(a);
}
return fun2;//将fun2作为fun1的返回值
}
let f = fun1();//f是一个全局变量,f=fun1()就相当于f=fun2,那么fun1()体内的a值也相当于变成了一个全局变量
f();//调用f(),就是在调用fun2(),因此成功获取了函数体内的值
6.获取函数体内值加强版
代码如下(示例):
function fun1(){
let a = 123;
function fun2(){
a ++;
console.log(a);
}
return fun2;
}
let f = fun1();
//f是全局变量,调用f(),相当于调用fun2();f时的变量已经成为了全局变量,因此每执行一次f(),就是在执行fun2(),a的值一直在发生变化.
f();//124
f();//125
f();//126
7.获取函数体内值匿名版
function fun1(){
let a = 123;
return function(){
return ++a;
}
}
let f = fun1();
console.log(f());//124
console.log(f());//125
console.log(f());//126
8.获取函数体内值自运行版
let f = (function(){
let a = 123;
return function(){
return ++a;
}
})();
console.log(f());//124
console.log(f());//125
console.log(f());//126
三、使用闭包的注意事项
1.由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,在IE中可能导致内存泄露。
2.闭包会在父函数外部改变父函数内部变量的值。
总结
1.为什么要用闭包?
答:如上面的例子,要想让a递增,我们可以调用fun2()的方法,但如果写了其它函数也让a递增那就达不到效果,为了确保a递增只能用fun2()的方法,那么就需要用到闭包,即保护里面的a递增时不受外界干扰.
2.最后再说一下概念:
答:闭包是一种保护私有变量的机制,在函数执行时形成私有的作用域,保护里面的私有变量不受外界干扰。直观的说就是形成一个不销毁的栈环境。