**
如何产出闭包:
**
当一个嵌套的内部子函数引用了外部父函数的变量(函数)时,这时就产出是闭包
**
闭包是什么:
**
理解一:闭包是嵌套的内部函数(大多数人都是主要理解)
理解二:包含被引用变量(函数)的对象(少数人)
注意:闭包存在与嵌套的内部函数中
判断闭包对象创建了几个就看外部函数调用了几次
产生条件:(这几个条件都满足才可以判断产生闭包)
1、函数嵌套
2、内部函数引用外部函数的数据(变量/函数)
3、执行外部函数
常见闭包:
1、将内部函数作为外部函数的返回值
function fn1() {
var a = 2;
//此时闭包已经产生
function fn2() {
a++;
console.log(a);
}
return fn2;//函数也是数据,是数据就可以传递,所以这里函数可以作为返回值
}
var f = fn1();
f();3//由于外部函数的返回值为内部函数,则f()就相当于内部函数fn2()
f();4
在上述的过程中,就产生了一个闭包
2、将函数作为实参传递给另外一个函数
例:
函数里面加定时器:
function(){
setTimeout(function(){//延时两秒
alert(‘dhwij’);
},2000)
}
这个就是典型的第二种闭包的例子
**
闭包的作用:
**
1、在函数内部变量(局部变量)在执行完后还可存活在内存中(延长了局部变量的存活周期)
2、可以让函数外部可以操作(读写)函数内部的数据(变量/函数都可,函数也是数据的一种类型)
问题:
1、局部变量在函数执行完成后还存在,在闭包中 存在与闭包中的变量才可能存在(这里的可以这个函数不是垃圾对象)
2、在函数外部可以直接访问局部变量吗?
不可以, 但是通过闭包让外部操作内部函数中的变量
**
闭包死亡:
**
包含闭包的函数为垃圾对象,则这个闭包死亡
**
闭包产生:
**
函数定义执行完,闭包产生(函数定义与函数执行不同)
**
闭包的应用:
**
定义JS模块
就是具有一定功能的JS文件
将所有数据和功能都封装在一个函数的内部(私有)
向外暴露一个包括n个方法的对象或函数
模块使用者通过调用暴露的方法来调用其中内部的方法
**
闭包的缺点:
**
1、函数执行完毕后,变量还在闭包中,内存得不到释放,占用内存实践较长
2、容易造成内存泄露
**
面试常问问题:
**
内存溢出和内存泄露:
内存溢出:当程序运行需要的内存大于剩余内存就出现内存溢出
内存泄露:
占用的内存没有及时的释放
内存泄露的多了就会出现内存溢出,从而出现错误
导致内存泄露的原因:
1、出现意外的全局变量
2、没有及时清理计时器或回调函数
3、闭包