「这是我参与2022首次更文挑战的第1天,活动详情查看:2022首次更文挑战」。
和我一样的小菜端看过来,大佬移步绕行吧em~,若有不足之处欢迎点评,但请嘴下留情 大家好~,我是丸子,我原本只是一个不想努力的小菜端(简称丸子菜端),一直在吃自己的老本,一直在做业务,就最近吧~,就看掘金看的,呦~ 嚯~ 这人写的真好👍,嘶~ 懂的这么多🐂🍺,查查这是个啥。大家给我卷起来了,就觉得不行啊,再不学习就出局了,年轻人的活力呢🤓,于是我就下定决心,温故而知新。奥利给~
Let's get to the point(咱进入主题吧)
我们从三个方向展开
graph TD
闭包是什么 --> 闭包的作用--> 闭包的注意点
1、闭包是个撒?
咱们就先举个🌰吧,看看代码
var closure = "闭包变量" //局部变量
function fn(){//这里的fn是一个函数
console.log(closure)//在函数里面能访问到外部变量
}
上面有一个局部的变量closure,一个函数fn,在fn函数可以访问到closure变量。就是一个闭包,意思就是:函数的内部能访问到其他函数的变量是一个闭包
有人会说,咦,你的闭包怎么和我见过的不一样,我见的是return了一个函数出去的, 对,就下面这样的😉
function fn1(){
var i = 1 //变量i
return function fn2(){
i++
return i
}
}
var funct = fn1()
funct()
在上面例子中有一个fn1的函数,内部有一个fn2的函数,这里面的闭包就是fn2和变量i组成的闭包。
可是为什么要一个函数套着一个函数?
因为需要局部变量,如果不用fn1函数套着,那么变量i就成为了一个全局变量,就不是使用闭包了。
函数嵌套一个函数仅仅是为了创造一个局部的变量,和形成一个闭包没有关系,但也算是闭包的一个前提吧先创建局部变量
为什么要fn2 return出去呢?
因为需要在外部访问到fn2这个函数,如果不return抛出去就无法使用,如果赋值给window上也可以访问到,所以return也仅仅是为了外部能到得到访问
2、闭包的作用是撒尼?
有两个作用:
1、能够读取函数内部的变量
2、能到让变量一直保持在内存中
function fn1(){
var i = 1;
newfn=function(){i+=1}
function fn2(){
alert(i);
}
return fn2;
}
var resolve=fn1();
resolve(); // 1
newfn();
resolve(); // 2
在上面的代码里,出现的闭包就是fn2,它运行了两次,第一次是1,第二次是2,因为fn1的局部变量一直存在内存中,并没有在被调用完清除。
为什么没有被清除,因为fn1是fn2的父亲函数,最后return出去了fn2,把return出去的fn2赋值给了一个全局变量,所以fn2依赖于fn1。
在执行第一次resolve()输出的是1,后续又调用了newfn()这个函数,特别要注意newfn=function(){i+=1}这一行,这是一个全局变量,因为前面并没有用var声明,所以在外部可以直接进行操作。调用了newfn()这个匿名函数后,i变量发生了变化,变2后又执行了fn2函数被return出去,所以resolve()第二次调用是2。
3、闭包注意撒子?
在我们面试的时候一问题闭包的缺点,大部分说的就是内存泄露,可是有的人或许不知道内存泄露是什么,内存泄露是值用不到的变量,依然占据内存空间,不能被再次利用。很多时候闭包里面的变量就是我们需要的变量,但是在使用闭包的同时函数的变量会被存到内存中,内存消耗会很大,在IE中会出现内存泄露,回收不了闭包里面的变量,解决方法就是在退出函数前,把不使用的函数局部变量删除