标签:
<script>
function f1()
{
var age = 18;
function f2()
{
alert(‘我今年:‘+age+‘岁‘);
}
return f2;
}
var func3 = f1();
func3();
</script>
闭包原理详解:----->JS的执行原理
首先,js执行分为两步骤,预编译阶段和执行阶段,明白了这个步骤,那么就以上述例子为例来慢慢分析(先花一点时间,看看上述代码,自己理解一下,再看下面的说明,效果更佳)
注:当我们在浏览器访问这个页面时,浏览器已经在瞬间完成了预编译和执行阶段
** 函数在声明时,会创建一个与之关联的活动对象(Active Object)也叫AO对象,AO里面包括很多东西,除了函数执行环境内的变量和函数的信息,还包括arguments对 象,scope属性,this对象等.
1. 预编译阶段:
1.1 在全局层面创建VO对象,vo对象包含全句的变量声明和函数,
伪代码: VO={ f1:function(){.....}}
1.2 进入函数f1 ,创建AO对象(AO对象和VO对象的角色一样,只是叫法不一样)
1.2.1 首先分析形参,函数没有形参,
1.2.2 再分析变量声明 有,AO{‘age‘:‘undefined‘}
1.2.3 再分析函数声明 有,AO{‘f2‘:‘function(){..}‘}
此时整个VO对象为:
VO和AO(活动对象)角色一样,只是叫法不一样,不用死扣.
VO{
f1:function()
{AO
‘age‘:‘undefined‘
‘f2‘:‘function()
{AO
scope:指向f1的AO对象 ###每个函数被声明时,都会创建一个与之关联的scope的属性
##scope总是指向定义函数时所在的环境
}‘ ##就因为有了scope,作用域链的效果才能体现出来,所以scope很伟大
scope:指向VO
}
}
2.执行阶段
2.1 f1(),执行,f1执行环境的AO对象:AO{‘age‘:18};
f2内的AO{‘age‘:18,scope:指向f1的执行环境}
2.2 func3(),执行,实际是在执行:f2(),而f2的AO{‘age‘:18,scope:指向f1的执行环境,alert(‘我今年:‘+age+‘岁‘)}
所以func3() 能接受到局部变量age 因此就能打印出18.
注:考虑到能更简单/易懂了解到闭包,所以上述代码在执行细节和执行情况做了简化,没有牵扯到太晦涩难懂的知识点(环境栈等),若想了解JS更高级的部分,推荐<Javascript权威指南>
如果有朋友还是不太懂闭包,js执行原理,可以留言,一起探讨.
标签:
原文地址:http://www.cnblogs.com/Lcoding/p/5860132.html