培训课题目记录1

-------------------------本文由博主原创并保留追责权利,如需转载请邮箱联系博主征得同意,并注明转载出处 博主邮箱:523893659@qq.com转载请注明出处,欢迎高手一起探讨----------------------------

今晚有同学问到我昨晚老师布置的题目,我看了一下觉得可以写写我的见解,让不懂的同学研究下,懂的同学来一起探讨。当然,不保证完全准确,最好有高手出现帮我纠出错误谢谢。

先放源代码:

图片
我给每一句话都标记了序号,来看看每句话程序分别都描述了些什么过程:
首先声明了一个函数体,名字叫f1。在f1的里面:
 ①:声明了1个变量赋值为999
 ②:突然出现一个没见过的变量nAdd,将一个函数体的地址赋值给nAdd。 
 ③:声明1个函数体,名字叫f2。这一步相当于:var f2=function(){....}
 ④:(如果f1被调用了的话)返回f2的地址 。

至此请注意:以上各项操作 均未开始执行!均未开始执行!均未开始执行!因为很重要所以说3遍。根据ECMA的语法规定:进行函数创建的时候,函数体的内容是不会被读取的,换句话讲就是——像我下面这么写一句,程序也不会报错 :
                                       function Fun(){  adsbfiabefgbbdsknfaskalsdbaiubewfwe.... }
接下来的步骤比较关键:
⑤:调用函数f1。并把f1执行后的返回值给 result。
       这一步调用了f1时,新建了一个  f1的活动对象(以下简称AO)  这个AO把上面的①②③④都确确实实的执行了一遍,也就是说,第⑤步执行完后,①②③④步均被执行,分别得到了下面的结果:
                                        1、f1的AO中存放了一个变量n,值为999。
                                        2、window下生成了一个变量nAdd,其中存放了新创建的函数体(假设这个函数体叫 “A” 注意,是假设。)的所在地址。这里我们分析一下②这句话的执行过程:nAdd对f1来说是一个从没见过的变量(从未被声明过),程序会(根据作用域链)逐层逐层往上找,最后发现即使是找到window下,也没发现有个叫nAdd的东西,所以程序就直接在window下声明一个nAdd。这就是我们所说的:一旦有个变量从来没见过,就会在window下生成这个变量  这句话的原理。  综上,②这句一旦被执行,window下面就会有一个nAdd,存放着函数体 A 的地址。
                                         3、在f1的AO下声明了 函数体 f2。
                                         4、返回f2存放的地址(给result)。
至此,result指向了一个写在f1的AO中的函数体,即f2。也就是说,接下来只要一调用result,就相当于调用f2函数。 

⑥:如上所说,执行result就等于执行f2。f2要求显示一个n变量,但f2中没有n,跳到它的上一层找,发现上一层有,所以第一次显示的是什么你懂的。
⑦:执行nAdd所指向的函数。这里我就提几个问题:
                                        1、nAdd为什么可以直接在外面用而不报错?
                                        2、nAdd所指向的函数存放在哪里?
                                        3、该函数执行了之后发生了什么事情?
                                        4、window下有新的n被生成么?
⑧:上面的4个问题都能搞懂的话那这一步我就不解释了。
另外再来一个问题:整段程序执行完之后,根据 正常情况下函数一旦被调用完毕就会释放其OA 的原则,f1的OA最后还在不在?为什么?如果还在的话又有多少个变量/对象被引住?

==========================分割线============================
 反正最后大概是像下图这样 :


 
总结:这几个月碰到过的闭包题当中,这题最简单。 
 
                                                            

posted on 2016-02-18 15:14  实习战地记者  阅读(137)  评论(0)    收藏  举报

导航