javascript执行上下文、作用域与闭包(第五篇)---一个例子的理解

在上一篇里,留下了一个例子,如果对那个例子不是太懂,没关系,我会在这一篇里详细讲一下我对这个例子的理解。

下面是这个例子:

function a(){
var age=21;
var height=178;
var weight=70;
function b(){
    alert(age);//undefined
    alert(height);//178
    var age=25;
    height=180;   //相当于是在全局作用域里声明了height变量。
    alert(age);//25
    alert(height); //180 
     }

      b();
}

a(); //备注:如果在函数作用域内声明变量不加var,相当于是在全局作用域里声明了这个变量。

为了更好的理解,我们变一下这个代码,


 var height;

function a(){

  var age=21;
  var height=178;
  var weight=70;
  function b(){

     alert(age); //undefined
     alert(height); //178
     var age=25;
     height=180;   
     alert(age); //25
     alert(height); //180

     }

  a();

我们来一步一步的理解这个例子:

第一步,在加载程序时,已经确定了全局上下文环境,并随着程序的执行而对变量就行赋值;
这里写图片描述

第二步,程序执行到第31行,调用a(),此时生成此次调用a()函数时的上下文环境,压栈,并将此上下文环境设置为活动状态
这里写图片描述

第三步,执行到第28行时,调用b(),生成此次调用的上下文环境,压栈,并设置为活动状态
这里写图片描述

(可不要忘了执行上下文的两个阶段,一个是创建阶段,一个是执行阶段,如果忘记了,赶紧翻一下我之前的文章哟)

到此,我们可以理解为什么第一个alert(age)的结果是undefined,从b()创建阶段时的上下文可知,age:undefined . 为什么语句height=180 没有在b()创建阶段时的上下文生成height:undefined?因为此时height=180是赋值语句,不是变量的声明语句。只有变量的声明语句才会在b()创建阶段时的上下文中生存相应的属性。

为什么第二个alert(height)的结果是178呢?这时候就要联系到作用域链的知识了,因为在b()的作用域所对应的执行上下文里没找到height的属性,所以从创建函数b()的作用域所对应的执行上下文里找相关属性,也就是a()的执行上下文,在a()的执行上下文里找到了height属性,它的属性值为178.

为什么第三个alert(age)的结果是25呢?这个就很好理解了吧,在b()执行阶段的上下文里,会完成对变量的赋值, 所以age赋值为25.

为什么第四个alert(height)的结果是180呢?因为height=180是个赋值语句,所以它就会找到height的属性,把它赋值为180,沿着作用域链,它在a()的上下文找到了height属性,并把它赋值为180,覆盖掉原来的属性值178.

如果理解了这个例子,是不是对执行上下文,作用域链的理解更深刻了呢。

我们在第一篇就讲到,闭包和执行上下文,作用域联系紧密,下一篇就来讲一讲在js中那个“深奥”的闭包。


下一篇: javascript执行上下文、作用域与闭包(第六篇)—闭包

如果还没懂的赶紧看一遍我之前的文章,并且一定要看懂噢。

javascript执行上下文、作用域与闭包(第一篇)—执行上下文
javascript执行上下文、作用域与闭包(第二篇)—作用域
javascript执行上下文、作用域与闭包(第三篇)—自由变量与作用域链
javascript执行上下文、作用域与闭包(第四篇)—作用域与执行上下文

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值