闭包的理解
1.如何产生闭包(条件)?闭包的三大要素是什么?
①函数存在嵌套关系
②内部函数必须引用外部函数变量对象上的局部变量
③外部函数必须执行
2.闭包到底是什么?
理解一:闭包是嵌套的内部函数(绝大部分人);
理解二:包含被引用变量(外部函数)的对象(极少数人);
**理解三:所谓的闭包是一个引用关系,该引用关系存在于内部函数中,引用的是外部函数的变量的对象(深入理解).**
3.常见的闭包
①将函数作为另一个函数的返回值(示例如下)
`function F1() {
var a = 100
return function () {
console.log(a)
}
}
var f1 = F1()
var a = 200
f1() //100`
②将函数作为实参传递给另一个函数调用(示例如下)
`function F1() {
var a = 100
return function () {
console.log(a)
}
}
function F2(f1) {
var a = 200
console.log(f1())
}
var f1 = F1()
F2(f1) //100`
③使用闭包实现私有方法操作独立的私有属性(可以理解为只支持被所处同一个类下的其他方法所调用)
`function counter() {
var num = 0;
function changeValBy(val) {
num += val;
}
return {
increment:function(){
changeValBy(1);
},
decrement:function(){
changeValBy(-1);
},
viewValue:function(){
console.log(num);
}
}
}`
4.闭包的作用(好处)
①延长外部函数变量对象的生命周期
②让函数外部可以操作(读写)到内部函数的数据(变量/函数)
③注意: 浏览器为了性能后期将外部函数中不被内部函数使用的变量清除了
5.闭包的生命周期
①在嵌套内部函数定义完时就产生了(不是在调用),外部函数调用的时候
②死亡:在嵌套的内部函数成为垃圾对象时
6.自定义模块(模块化)
具有特定功能的js文件
将所有的数据和功能都封装在一个函数内部(私有的)
只向外暴露一个包含n个方法的对象或函数
模块的使用者,只需要通过模块暴露的对象调用方法来实现对应的功能
使用自调用和不使用自调用函数区别
自调用(外层套匿名函数自调用,内部用window.xxx把能够暴露的属性直接添加给window,方便外部使用)
不使用自调用(普通函数,接口可以暴露一个对象return,对象内部包含能够暴露的数据,外部通过调用,比如var a = xxx( ).然后通过
a.xxx( ) 来使用)
7.闭包的缺点和解决(内存泄漏和内存溢出)
内存泄漏:内存无法释放;
内存溢出:内存被撑爆;
f = null ;解决方式 ;让闭包机制清除,必须删除外部函数调用的时候生成的(定义的那个对应内部函数);
8,经典案例(循环中创建闭包)
代码如下:
`for(var i=0;i<10;i++){
setTimeout(function(){
console.log(i);
},100);
}`
出现的问题:
1.为什么十次打印值都一样?
答:正如闭包的第二点应用一样,这十个打印函数都处于同一作用域链下,是共享同一环境的闭包,它们访问是同一个i值,所以打印出来的值都一样。
2. 为什么打印出来的值是10?
答:这与setTimeout的运行机制有关系,setTimeout是一个异步函数,当他被调用后,是不会立即执行的,而是添加到当前任务队列后面,直到之前的任务都执行
完毕后才会执行。
执行的过程:
for循环每执行一次,就将一个setTimeout任务添加到队尾,直到for循环执行完毕,才会开始执行十次setTimeout任务,然而此时的i已经变成了10,所以就会打
印出十次10啦!
解决方法:
1.利用闭包应用的第三点,让每个打印函数成为独立的闭包,并利用闭包保存当前循环的i值:(类似于一个匿名函数)
`for(var i = 0; i<10;i++) {
(function func(j) {
setTimeout(function() {
console.log(j);},100)
})(i);
}`
2.因为过多的闭包会占用更多的内存,所以为了避免在不必要的时候使用闭包,我们可以采用let关键字:
`for(let i=0;i<10;i++){
setTimeout(function(){
console.log(i);
},100);
}`
闭包的使用场景参考网站:https://blog.csdn.net/qq_21132509/article/details/80694517
https://www.cnblogs.com/Renyi-Fan/p/11590231.html