本文已参与「掘力星计划」,赢取创作大礼包,挑战创作激励金。
绝对不是标题党!
😢什么鬼,一次技术分享竟然搞出来俩种闭包 ?
当使用Chrome的控制台看到闭包的判断,我惊了,这还是我认识的闭包吗.....
一. Chrome里的闭包判断
直接上来就来个闭包demo看看
var m
function demo1() {
var num = 10;
function inner() {
console.log(num)
debugger
}
m = inner;
}
demo1()
m()
让我们打开Chrome的控制台看一下
???什么鬼
难道不应该是inner的闭包吗 我赶紧翻开小书寻找一手
二. "教材"中的闭包
教材选自--《你不知道的JavaScript》上卷
-
foo()函数的返回值,返回了内部函数bar()
-
外部定义了baz把foo()的返回值赋值给了它,外部调用了baz,实际上就是等于引用调用了内部函数bar()
-
那么这个引用bar()就被称为了闭包
😂 看到了这,已经是大无语事件了,到底哪种是对的呢?
其实并没有准确的判定闭包的定义,相比于教材上的判断,Chrome里面直接看到会更加直观一点把!
三. 说一下自己对于闭包概念的理解吧
我是看不懂教材上面的解释,可能我太笨了...
闭包的判定
当一个函数运行时形参或者其私有变量被内部函数所引用,满足这个条件时,那么这个函数就会形成闭包。
来个demo看看
对第一个demo 跟 不做引用的例子做个对比
var a,b
function demo1() {
var num = 10;
function inner() {
console.log(num) // 对外部函数demo1的num进行了引用
debugger
}
a = inner;
}
demo1()
a()
function demo2() {
var num = 10;
function inner() {
console.log("打印一下把") //没有引用任何变量,只做打印
debugger
}
b = inner;
}
demo2();
b();
从两张图中就可以看出 闭包的判定 跟内部函数是否引用外部函数变量有关
当多个内部函数都存在时,只要有内部函数存在引用外部变量,其他内部函数共享外部函数的变量和形参
var a
var demo3 = function(){
let name = '标题党'
function inner1(){
console.log('我是第一个内部函数')
debugger
}
function inner2(){
console.log('我是第二个内部函数')
}
function inner3(){
console.log(name)
}
a = inner1
return inner3
}
demo3()
a()
四. 闭包使用不当带来的问题 划重点是** 使用不当 **
🤔别上来就闭包带来的问题!
看清楚标题再看下面,不是闭包带来的问题,是使用不当造成的内存泄漏情况。
先来个demo
<button onclick="onClick()">点我就能看到闭包泄漏</button>
<script>
let result = []
function demo4 () {
let arr = new Array(10000)
let num = 666
function inner() {
let name = '标题党'
}
inner()
return arr
}
function onClick() {
result.push(demo4())
}
</script>
操作方法:
1. 打开Chrome控制台点击性能页面,左侧圆圈代表开始录制,垃圾桶图标表示执行垃圾回收机制.
2. 点击录制,先执行一次垃圾回收(为了录制出来更好区分基准线),点击按钮,连续点击几次,本次以四次为例,在点击完按钮后, 重点来了 --最后一定要执行一次垃圾回收(模仿JS自动回收内存情况)
3. 展示效果如下,我们通过图中可以看出每次点击按钮,堆内存都会增加一个梯度,执行完四次之后,执行一次垃圾回收,发现梯度下降,但是堆内存没有完全消失,留了一部分梯度,这就是说明存在内存泄漏的情况
😁继续探索内存泄漏问题
看不懂英文的不会设置一下嘛~
操作方法:
点击内存(Memorize)页面,选择第二个选项(以时间轴的方式展示内存分配情况),点击开始,执行几次点击按钮事件,最后执行一次垃圾回收机制,效果如下方第二张图片.
😜定位内存泄漏问题
内存页面第一个选项点击开始时,如果报错的话,进无痕模式,先在性能页面录制重复一下操作,再到内存页面选择第一个选项,多试几次.
操作方法:
还是内存页面,点击选项第一个,点击下方拍摄快照.
下一步,重点来了,执行几次点击事件,重新执行一下拍摄快照,页面会出现两个快照
选择下方图片内红色框内的第三个选项,这个选项是只显示快照2和快照1的区别.
🤣这样我们就定位到了内存泄露的位置了
内存泄漏例子来自于 一文带你了解如何排查内存泄漏导致的页面卡顿现象
👌总 结
闭包其实在我们项目中无处不在的,模块化就是代表作之一.
合理使用闭包,你才能发现他的魅力,使用不当会造成内存泄漏的哦!