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

本文详细解析了JavaScript中变量的作用域规则,通过具体实例说明了全局变量与局部变量的访问机制,以及变量提升等概念。

  代码变成下面的样子

    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.

所以后面不论是函数内部还是全局中执行 alerta),都会在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个类似的实例,我在坛子里看见有人贴的帖子有4js的面试题,我讲前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属性。

                 正式执行sayHia=20globalContext.VO标识符解析,查找:sayHi.Ao——globalContext.VO,在globalContext.VO中找到,将其值修改为20

                 alert(a);  标识符解析,查找:sayHi.Ao——globalContext.VO,在globalContext.VO中找到,弹出20.

                  sayHi执行完毕,

               执行全局alert(a), 只能在globalContext.VO中查找,找到(已经被修改为20啦)

               弹出20  全部代码完毕



不要觉得这么简单的东西在这啰嗦这么多,我也没办法,程序执行时就是发生了这么多事情。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值