准确来说,闭包是基于正常的垃圾回收处理机制下的。也就是说,一般情况一个函数(函数作用域)执行完毕,里面声明的变量会全部释放,被垃圾回收器回收。但闭包利用一个技巧,让作用域里面的变量,在函数执行完之后依旧保存没有被垃圾回收处理掉。
闭包
定义
MDN定义
javascriptkit
词法作用域
作用域链
函数在执行的过程中,先从自己内部找变量如果找不到,再从创建当前函数所在的作用域(词法作用域)去找, 以 此往上注意找的是变量的当前的状态
作用域链的博客
函数连同它作用域链上的要找的这个变量,共同构成闭包
一般情况下使用闭包主要是为了
封装数据
暂存数据
一个典型的闭包案例
当函数内部没有执行以下的代码时
在代码执行完成后,函数内部的局部变量speed就会被销毁,由于全局标量speedUp一直存在(除非关闭当前页面,否则全局变量一直存在),那么函数内部的作用域就没有办法被销毁,里面有东西一直被使用,这点与浏览器的垃圾回收机制相仿,当我们执行speedUp(),他会在函数的词法作用域下去寻找,函数里面又返回了一个fn,因而形成闭包,简单的理解为
这一段代码形成一个闭包,如果不return fn,那函数内部的局部变量就会被销毁。
我们可以看看上述代码利用立即执行语句和立即执行函数可以怎么演变:
闭包的相关案例
如下代码输出多少?如果想输出3,那如何改造代码?
同等演变
假设只有两层循环:
改造后(立即执行语句,演变过程)
封装一个 Car 对象
如下代码输出多少?如何连续输出 0,1,2,3,4
输出结果为:delayer:5(连续输出5个),执行setTimeout时,代码会挂到任务队列中区,待i遍历完成之后执行,而此时i = 5,所以输出delayer:5(连续输出5个)
修改后
或者
如下代码输出多少?
补全代码,实现数组按姓名、年纪、任意字段排序
写一个 sum 函数,实现如下调用方式
最后,“相信有很多想学前端的小伙伴,今年年初我花了一个月整理了一份最适合2018年学习的web前端干货,从最基础的HTML+CSS+JS到移动端HTML5等都有整理,送给每一位前端小伙伴,53763,1707这里是小白聚集地,欢迎初学和进阶中的小伙伴。”
祝大家早日学有所成,拿到满意offer,快速升职加薪,走上人生巅峰。