您的位置:首页 > Web前端 > JavaScript

献给各位新手——真正搞清楚javascript闭包(2)

2012-08-04 12:23 260 查看
代码变成下面的样子
function outerFun()
{
//没有var
a =0;
alert(a);
}
/*var a=4; 请注意,我把这段代码注释掉了*/
outerFun(); //0
alert(a); //0
结果还是都弹出0
现在不论是全局还是函数内部都没有var定义的变量了,预编译阶段全局变量中不会有a这个属性,在outerFun执行环境创建时,outerFun.AO中也不会有这个叫a的属性。
当outerFun真正被执行的时候,发生a=0写入操作,按照顺序在outerFun.AO——globalContext.VO中都找不到a属性,由于是写操作,js就会自动的在globalContext.VO中添加一个a属性,并立刻写入值:0.
所以后面不论是函数内部还是全局中执行 alert(a),都会在globalContext.VO中查找到a属性了,就都弹出0.
我再修改一下
function outerFun()
{
//没有var
a =0;
alert(a);
}
alert(a); //错误,找不到a
outerFun(); //0
这里就会提示错误,由于先执行弹出(读)操作,我之前也说了, 在预编译阶段, globalContext.VO中是不会有a属性的(还记得么,预编译阶段globalContext.VO只看看有没有var定义的变量和函数声明),现在要直接执行a读操作,js还没来得及为globalContext.VO添加a属性(上面是先发生写入操作,globalContext.VO顺利添加属性a并赋值)所以就报错了。
最后再简单讲2个类似的实例,我在坛子里看见有人贴的帖子有4道js的面试题,我讲前2个,看懂了,后2个就能分析出来
var a = 10;
sayHi(); //20
function sayHi() {
var a = 20;
alert(a);
}
alert(a); //10

预编译完成,globalContext.VO.a=undefined,
globalContext.VO.sayHi=sayHai 对象。
从上往下执行代码,
var a = 10; 执行完后,globalContext.VO.a=10
轮到执行sayHi(), 先创建执行环境,分配作用域链(sayHi内部有var定义的变量),所以 sayHi.Ao=undefined。
作用域链分配完毕:sayHi.Ao——globalContext.VO
记住,正式执行sayHi函数之前,上面的操作就已经完成了。
开始正式执行内部代码: var a = 20; 发生标识符解析,按顺序查找 :sayHi.Ao——globalContext.VO
在sayHi.Ao中找到a,执行写入操作,sayHi.Ao.a=20;
alert(a) 标识符解析 查找:sayHi.Ao——globalContext.VO,找到sayHi.Ao中a=20;
弹出20
sayHi()执行完毕
执行全局中 alert(a); 只能在globalContext.VO中查找,找到a,弹出10 完毕
第2个
var a = 10;

sayHi();

function sayHi() {

a = 20;

alert(a);

}

alert(a);
预编译阶段一样
执行到sayHi,创建sayHi执行环境阶段,
没找到var ,sayHi.Ao中不会有a属性。
正式执行sayHi,a=20,globalContext.VO标识符解析,查找:sayHi.Ao——globalContext.VO,在globalContext.VO中找到a ,将其值修改为20
alert(a); 标识符解析,查找:sayHi.Ao——globalContext.VO,在globalContext.VO中找到a ,弹出20.
sayHi执行完毕,
执行全局alert(a), 只能在globalContext.VO中查找,找到(已经被修改为20啦)
弹出20 全部代码完毕

不要觉得这么简单的东西在这啰嗦这么多,我也没办法,程序执行时就是发生了这么多事情。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: