同样面试中需要对一个知识点掌握的很好才能引起面试官的重视。作为前端的一只菜鸡在这里给大家说说我对闭包的理解。
1.初识闭包:
我们知道js里面内部函数可以访问外部函数里面的变量,不能外部函数不能访问内部函数里面的变量。有什么东西可以将内部函数和外部函数关联起来呢?-------闭包
刚开始接触闭包的时候就是觉得闭包就是将内外函数连接起来可以让外部函数可以访问到内部函数里面的变量
2.走进神话
接下来看一下“你不知道的js里面的一段代码”
function wait(message){
setTimeout(function timer(){
console.log(message);
},1000);
}
wait("王涵是个猪");
我们都知道js里面的setTimeout会放到同步任务执行完之后才去执行的【setTimeout的默认时间是4毫秒】,这个时候你可能就会犯嘀咕了!将其中的timer函数放在同步任务执行完之后才去执行,能否打印出“王涵是个猪"这句话呢?
揭开谜底,这里是能打印出来的。
闭包-------------------------将内部函数放到它所在的词法作用域之外去执行,但是它都会持有对原始定义作用域的引用。
其实在定时器,事件监听器,ajax请求,跨窗口通信,web Worker或者任何其他异步(或者同步)任务中,只要调用了回调函数实际上就是使用闭包。
3.看看闭包和循环的应用吧!
for(var i=0;i<5;i++){
setTimeout(function(){
console.log(i);
},i*1000);
}
这算一个比较经典的例子了
先说说我刚刚开始的想法吧!哇!每1000毫秒打印一个值,那打印出来的不就是0,1,2,3,4。我还考虑到了其中的是每隔1000毫秒才会去打印,我简直太机智了。
哇!你要是跟我的回答是一样的!你真的对其中的定时器掌握的很好呀!揭晓谜底吧!5,5,5,5,5
其中的延迟函数都是放在同步函数执行完之后才去执行的。所以首先进行的是其中的循环,当循环执行完之后才去执行定时器里面的函数,等这些函数再去执行的时候就会回到原来的词法作用域里面查找其中的变量i的值,因为跳出循环这个时候原来的词法作用域里面保存的变量i的值是5。
本文主要讲的是闭包是什么!如何避免打印出来的一直都是5。你们可以了解一下其中的let和立即执行函数(IIFE)。我们还需要注意的就是其中setTimeout的默认时间是4毫秒的。
这里我还需要注意的就是我们可以看到闭包中会保存原来的词法作用域,因此会存在内存泄露。大量的使用闭包也会有让页面的性能下降很多。
想去对其中的js的垃圾回收机制,其中的闭包的应用和其中的let了解更多的话可以去看看我的其他的博客呦!