前言
任务四 闭包(Closures)
闭包在JS中是很重要的概念,他们让JS出色地完成异步任务。
为了能更好的理解闭包,我们先来看作用域链的例子:
someFunc()
↑
|
inner()
↑
|
foo()
我们称someFunc()
声明了一个变量bar
:
someFunc()
var bar
↑
⋮
有了嵌套作用域的知识,我们可以说inner()
有权访问bar
:
someFunc()
var bar
↑
|
inner()
alert(bar)
↑
⋮
inner()
可以说 包住了 bar
. 所以 inner()
是一个 闭包 .
为了回调式的编程,即使inner()
不立即执行,闭包也会保持。在JS中将inner
传来传去,或者稍后在someFunc()
中返回出来也是可以的,而在这个过程中,bar
将一直是可用的。
你的任务
修改之前的代码,设置zip()
中的bar = true
,然后在foo()
中将zip
return
出来。
完成后, 执行scope-chains-closures verify <your-file.js>
来验证你的答案
任务五 垃圾回收机制 (Garbage Collection)
在JS中,内存是被运行时环境(runtime)自动管理的。运行时环境决定了已用内存的释放。而这个决策过程就称之为 垃圾回收机制
每一个JS运行环境都有自己的垃圾回收机制的算法,但是大多数用的都类似:标记&清除
算法,这个算法的原理即:
只标记活动代码中可达的内存的引用(变量,函数等),任何引用只要没有被标记,就会被垃圾回收掉(即该块内存被释放掉)
而这个标记可达内存的概念也一定程度上和闭包有关:
someFunc()
var bar
return inner
↑
|
inner()
alert(bar)
↑
⋮
当闭包inner()
被someFunc()
return掉,它仍然保持了对bar
的引用,这时标记&清除
算法就会标记bar
可达,因此bar
也就不会被垃圾回收掉。
对inner()
来说,为了能正确解析对bar
的引用,不仅需要保持存放bar
的这块内存,而且需要保持可以访问到bar
的这条作用域链。
一旦对inner()
的引用不再需要,就可以对其进行垃圾回收了,这也意味着bar
也可以被垃圾回收,最终整条作用域链都被回收掉,内存被释放。
所以说,作用域,作用域链,闭包,垃圾回收机制,他们都是息息相关的!
你的任务
你需要用Chrome的DevTools来检验垃圾回收机制的运行。按以下的步骤来感受一下垃圾回收:
1) 在Chrome中开一个tab
2) 打开DevTools > Timeline tab
3) 确保设置和下图一致:
a) 取消选中 Frames View (allows seeing memory graphs)
b) 选中 Flame Chart View (allows seeing where execution time is spent)
c) 选项中只选择 "Memory"
4) 点击灰色圆形按钮开始搜集数据
5) 随便访问一个网站http://www.baidu.com
6) 点击红色的录制按钮停止搜集数据
7) 然后你家能看到类似下图:
8) 我们要关注的是内存突然减少的地方:
9) 选择这部分突然减少的内存
10) 看那个叫"GC Event"的黄色部分:
11) 然后就能看到回收的总内存量和耗时
有趣的事情是,GC的耗时:一般远远超过16ms(这个能保持60fps的最大值)。同时当GC发生时会阻塞主线程,所以如果你的程序很卡,就可能是大量GC惹的祸。
Note: 你如果有强迫症,也可以继续运行 scope-chain-closures verify
完
翻译仓促,如有错误欢迎指出!点赞更好哦~
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。