1、什么是闭包
闭包
指的是引用了另一个函数作用域的变量的函数,通常是在嵌套函数中实现
在 JavaScript 中,闭包会随着函数的创建而被同时创建。
2、如何产生闭包
当一个嵌套的内部函数引用了嵌套的外部函数的变量时,就产生了闭包
3、产生闭包的条件
函数嵌套
内部函数引用了外部函数的数据(变量/函数)
例子
<script>
function fn1(){
var a = 2
var b = 'abc'
function fn2(){//执行函数定义就会产生闭包(不用调用内部函数)
console.log(a);
}
fn2()
}
fn1()
</script>
4、常见的闭包
将函数作为另一个函数的返回值
<script>
function fn1(){
var a = 2
function fn2(){
a++
console.log(a);
}
return fn2
}
var f = fn1()
f()//3
f()//4
</script>
将函数作为实参传递给另一个函数调用
5、闭包的作用
1)、使用函数内部的变量在函数执行完毕后,仍然存活在内存中(
延长了局部变量的生命周期
)
2)、让函数外部可以操作(读/写)到函数内部的数据(变量/函数)
6、闭包的生命周期
1)、产生:在嵌套内部函数定义执行完成时就产生了(不是在调用时)
2)、死亡:在嵌套的内部函数成为垃圾对象时
7、闭包的应用
定义JS模块
具有特定的功能的JS文件
将所有的数据和功能都封装在一个函数内部(私有的)
只向外暴露一个包含n个方法的对象或函数
模块的使用者,只需要通过模块暴露的对象调用方法来实现对应的功能
(function(){
// 私有数据
var msg = 'My atdd'
// 操作数据的函数
function doSomething(){
console.log('doSomething()'+msg.toUpperCase());
}
function doOtherthing(){
console.log('doOtherthing()'+msg.toLowerCase());
}
window.myModule2 = {
doSomething,
doOtherthing
}
})()
<script src="./myMoudle.js"></script>
<script>
myModule2.doSomething()
</script>
8、闭包的缺点及解决
缺点:
函数执行完后,函数内的局部变量没有释放,占用内存时间会变长,容易造成内存泄漏
解决:
1)、能不用闭包就不用
2)、及时释放
内存泄漏:
<script>
// 意外的全局变量
function fn(){
var arr = new Array(1000000);
console.log(arr);
}
f()
// 没有及时清理的计时器或回调函数
var intervalId = setInterval(function(){
console.log('----');
},1000)
// clearInterval(intervalId)
</script>
闭包例子1
<script>
var name = "The Window"
var object = {
name:"My Object",
getNameFunc:function(){
return function(){
return this.name
}
}
}
alert(object.getNameFunc()())//The Window
var object2 = {
name2:"My Object",
getNameFunc:function(){
var that = this
return function(){
return that.name2
}
}
}
alert(object2.getNameFunc()())//My Object
</script>
闭包例子2
<script>
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);//undefined,?,?,?
var b = fun(0).fun(1).fun(2).fun(3);//undefined,?,?,?
var c = fun(0).fun(1);c.fun(2);c.fun(3);//undefined,?,?,?
</script>