一.闭包的概念以及特性
- 概念:在函数的内部定义一个函数,使其能够读取其他函数的局部变量
- 作用:读取其他函数的内部变量,是将函数的内部和外部连接起来的桥梁,可以用来实现模块化
- 形成条件:函数的嵌套
- 特性:
- 封闭性:外界无法访问闭包内的数据,除非闭包向外界主动提供接口
- 持久性:一般函数在被系统调用之后都会被注销掉,对于闭包而言,当外部函数被调用之后不会被立即注销
- 优缺点:
- 优点:延长外部函数局部变量的生命周期
- 缺点:过多的占用内存,造成内存泄漏
- 注意:所有闭包中的this都是指向window
- 语法:
var fun1 = () => {
var num = 999;
var fun2 = () => {
return num
}
return fun2;
}
fun1()();
二.有关闭包的常见面试题
- 打印计时器的值
for (var i = 0; i < 5; i++) {
setTimeout(function () {
console.log(i);
}, 0)
}
for ( var i = 0 ; i < 5 ; ++i ) {
(function(cacheI){
setTimeout(function(){
console.log(cacheI);
},0)
})(i)
} ;
for (let = 0; i < 5; i++) {
setTimeout(function () {
console.log(i);
}, 0)
}
- 函数返回值
function fun(n,o) {
console.log(o)
return {
fun:function(m){
return fun(m,n);
}
};
}
var a = fun(0); a.fun(1); a.fun(2); a.fun(3);
var b = fun(0).fun(1).fun(2).fun(3);
var c = fun(0).fun(1); c.fun(2); c.fun(3);
第一行:
可以得知,第一个fun(0)是在调用第一层fun函数。
第二个fun(1)是在调用前一个fun的返回值的fun函数
第后面几个fun(1),fun(2),fun(3),函数都是在调用第二层fun函数。
在第一次调用fun(0)时,o为undefined;
第二次调用fun(1)时m为1,此时fun闭包了外层函数的n,也就是第一次调用的n=0,即m=1,n=0,
并在内部调用第一层fun函数fun(1,0);所以o为0;
第三次调用fun(2)时m为2,但依然是调用a.fun,所以还是闭包了第一次调用时的n,
所以内部调用第一层的fun(2,0);所以o为0;
第四次同理;
即:最终答案为undefined,0,0,0
第二行:
先从fun(0)开始看,肯定是调用的第一层fun函数;
而他的返回值是一个对象,所以第二个fun(1)调用的是第二层fun函数,后面几个也是调用的第二层fun函数。
在第一次调用第一层fun(0)时,o为undefined;
第二次调用 .fun(1)时m为1,此时fun闭包了外层函数的n,也就是第一次调用的n=0,即m=1,n=0,
并在内部调用第一层fun函数fun(1,0);所以o为0;
第三次调用 .fun(2)时m为2,此时当前的fun函数不是第一次执行的返回对象,而是第二次执行的返回对象。
而在第二次执行第一层fun函数时时(1,0)所以n=1,o=0,返回时闭包了第二次的n,遂在第三次调用第三层
fun函数时m=2,n=1,即调用第一层fun函数fun(2,1),所以o为1;
第四次调用 .fun(3)时m为3,闭包了第三次调用的n,同理,最终调用第一层fun函数为fun(3,2);
所以o为2;
即最终答案:undefined,0,1,2
第三行:
fun(0)为执行第一层fun函数,
.fun(1)执行的是fun(0)返回的第二层fun函数,这里语句结束,
遂c存放的是fun(1)的返回值,而不是fun(0)的返回值,
所以c中闭包的也是fun(1)第二次执行的n的值。
c.fun(2)执行的是fun(1)返回的第二层fun函数,
c.fun(3)执行的也是fun(1)返回的第二层fun函数。
在第一次调用第一层fun(0)时,o为undefined;
第二次调用 .fun(1)时m为1,此时fun闭包了外层函数的n,
也就是第一次调用的n=0,即m=1,n=0,并在内部调用第一层fun函数fun(1,0);所以o为0;
第三次调用 .fun(2)时m为2,此时fun闭包的是第二次调用的n=1,即m=2,n=1,
并在内部调用第一层fun函数fun(2,1);所以o为1;
第四次.fun(3)时同理,但依然是调用的第二次的返回值,遂最终调用第一层fun函数fun(3,1),
所以o还为1
即最终答案:undefined,0,1,1