skyADMIN

JS闭包小例子

前端面试时候一个很喜欢问的问题就是闭包,说实话我当时面试的时候是没有用过闭包的(《你不知道的JS》里告诉我们,咱写的JS代码里充斥着闭包,只是我们不知道那是闭包,嗯,但是,你明白我的意思就好),所以一开始问我我是懵逼的,后来我读了下书,JS高程里把这个概念写得很清楚,但是我感觉是一段废话,除了背给面试官听没有任何意义。还是没有写过闭包,还是不知道什么时候写闭包,什么场景用闭包。

最近写了一段代码,加上今天看的书(对,就是《你不知道的javascript》),感觉对闭包有了一点理解,记录一下。

最近写了一段什么代码呢?具体的记不太清了,大概意思就是在for循环里用了一个函数,函数里用了循环次数记录变量,啊算了,记不太清楚了,还是拿书里的例子来说算了。这个例子是这样的,for循环,每隔一秒输出一个,分别输出1、2、3、4、5。简单写个不理解闭包,入门水平JS程序员的代码(说的就是我):

y9tj0nwl58mv71uiukk

(我怎么这么不爱用那个代码块功能写文字出来呢)

执行结果是,每隔一秒,输出一个6。仔细想想不难理解。首先我们知道,JS是单线程异步的,所以setTimeout只是注册了一下事件,循环不等它,继续执行着。好的,在非常短(我也不知道是多短,但是肯定比1秒短)的时间里,循环执行完了,挂了5个事件到事件队列里(我现在对我的用词有点担心,上次有个技术分享没有认真听,反正就是一个队列),然后等到了相应的时间,就会执行timer函数。timer函数要输出i,timer函数里没有i,那就向上级作用域里找,找到了,i是6。输出6。

OK,我觉得我解释清楚为什么会输出6了。好的,那么,怎么解决这个问题?就是要能让timer函数执行的时候,i要能是我们期望的值呗。怎么做呢,让他的作用域里有i这个值并且i这个值等于循环的每一次那个值就OK了呗。好的,那问题就变成,怎么给每个timer函数一个作用域,且那个作用域里的i都是我们希望的i。

弄个作用域,函数呗,因为只是想要个作用域,就写个立即执行函数吧:

1slkr9ygg8zscfzud9

这样,timer函数就有个立即执行函数生成的作用域了~but,这个代码还是会失败的,因为,这个作用域是空的,查找这个作用域里找不到i,还是会继续向上一级作用域查找,还是6!所以最后一步,把i弄进去。此处请看清楚参数!

t97djdehdh0nyzw0x2v

其实我就是把《你不知道的javascript》那一节整理了一下……希望之前不懂闭包的前端同学能通过这篇原(chao)创(xi)的文章理解闭包~

码字很辛苦,转载请注明来自环宇博客《JS闭包小例子》

评论