一、闭包
1.1 产生闭包的条件?
- 函数嵌套
- 内部函数引用了外部函数的数据(变量/函数)
<script>
function fn1(){
var a = 2;
var b = "abc";
function fn2(){ //执行函数定义就会产生闭包(不用调用内部函数)
console.log(a);
}
fn2();
}
fn1();
</script>
1.2 常见的闭包
- 将函数作为另一个函数的返回值
- 将函数作为实参传递给另一个函数调用
<script>
// 1.将函数作为另一个函数的返回值
function fn1(){
var a = 2;
function fn2(){
a++;
console.log(a);
}
return fn2;
}
var f = fn1(); //此时闭包产生
f(); //3 //闭包还未消失
f(); //4 //闭包还未消失
f=null; //闭包消失(后面生命周期会说到)
// 2.将函数作为实参传递给另一个函数调用
function showDelay(msg){
function(){
alert(msg);
}
}
showDelay("学 习"); //此时闭包产生后 执行结束会立刻消失(此处与上面不同)
</script>
1.3 闭包的作用
- 延长了局部变量的生命周期
- 让函数外部可以操作(读写)到函数内部的数据(变量/函数)
注意:
一般情况下,在函数执行完后,函数内的局部变量会立即释放,但闭包可以使局部变量不被释放,延迟生命周期。
一般情况下,在函数外部不能直接访问函数内部的局部变量,但闭包可以让外部操作它。
1.4 闭包的生命周期
- 产生:内部函数被定义时就产生了(不是在调用)
- 死亡:内部函数不被引用,被标记为垃圾对象时
function fn1(){
var a = 2;
function fn2(){
a++;
console.log(a);
}
return fn2;
}
var f = fn1(); //fn1被调用,内部fn2被定义,闭包产生
f(); //3 //相当于fn2() 闭包还未消失
f(); //4 //相当于fn2() 闭包还未消失
f=null; //f不指向fn2 内存释放,闭包消失
1.5 闭包的应用_自定义JS模块
- 将数据和功能都封装在一个函数内部(私有的)
- 向外暴露一个包,执行n个方法的对象或函数
- 当使用时,只需要引入模块,来调用方法来实现对应的功能
<script src="myModule.js"></script>
<script>
myModule2.doSomething();
myModule2.doOtherthing();
</script>
myModule.js
(function(){
var msg = "My Class";
// 操作数据的函数
function doSomething(){
console.log("doSomething()"+msg.toUpperCase());
}
function doOtherthing(){
console.log("doOtherthing()"+msg.toLowerCase());
}
// 向外暴露对象(给外部使用的方法)
window.myModule2 = {
doSomething:doSomething,
doOtherthing:doOtherthing
}
})()
1.6 闭包的缺点
1.缺点:
- 函数执行完后,函数内的局部变量没有释放,占用内存时间会变长
- 容易造成内存泄漏