培训课题目记录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最后还在不在?为什么?如果还在的话又有多少个变量/对象被引住?
==========================分割线============================
反正最后大概是像下图这样 :

总结:这几个月碰到过的闭包题当中,这题最简单。
浙公网安备 33010602011771号