持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第18天,点击查看活动详情
铃铛说点题外话
一句话前情回顾:闭包的两种表现形式:1. 返回一个函数。2.作为函数参数传递
一句话介绍今天:闭包的第三种表现形式:定时器、事件监听等,只要使用了回调函数,实际上就是在使用闭包。
闭包的最后篇
铃铛说正文
闭包除了之前说的返回一个函数和作为函数参数传递这两种形式之外,还有一种很常见的表现形式:回调函数
- 定时器
setTimeout(() => {
console.log('111');
},100)
定时器里面的箭头函数实际上是一个回调函数,回调函数实际上就是一个闭包,本质上也是在一个函数里面定义了一个函数
- 事件监听
$('#app').click(function(){
console.log('DOM Listener');
})
其实这里也是一个回调函数,所以本质也是闭包
- 立即执行函数
var a = 2;
(function IIFE(){
// 输出2
console.log(a);
})();
立即执行函数表达式创建闭包, 保存了全局作用域window和当前函数的作用域,因此可以访问全局的变量
下面看一个日常常见的一个问题:循环输出
for(var i = 1; i <= 5; i ++){
setTimeout(function timer(){
console.log(i)
}, 0)
}
这道题我们想要的输出是:1,2,3,4,5,6但是实际上输出的却全是6。这又是为什么呢?setTimeout定时器是一个宏任务,由于JS是单线程语言,根据eventLoop事件循环机制,在主线程同步任务执行完后才去执行宏任务,因此循环结束后setTimeout中的回调才依次执行,但输出i的时候当前作用域没有,往上一级再找,发现了i,此时循环已经结束,i变成了6。因此会全部输出6。
跟铃铛说再见
学习的最后一步:放松
今日冷笑话:小企鹅有一天问他奶奶,“奶奶奶奶,我是不是一只企鹅啊?”“是啊,你当然是企鹅。” 小企鹅又问爸爸,“爸爸爸爸,我是不是一只企鹅啊?”“是啊,你是企鹅啊,怎么了?”“可是,可是我怎么觉得那么冷呢?”
放松结束,猜猜明天会说讲些什么吧