javascript的作用域

javascript的作用域

前几天我们解释了js的预编译,今天接着说一下作用域,作用域这个词我相信大家都不会太陌生,比如说我们定义一个函数,一个函数就像一个屋子一样,屋子的形成就好像是形成了一个单独的域,和外界有一些阻隔,里边能看到外边,外边看不到里边,两个屋子之间是彼此独立的。这样我们可以把这个函数所生成的这个空间管他叫做一种作用域,但是,他不精准。

作用域确实是因为函数的产生而产生的独特的东西。也就是说:作用域属于函数,一个函数产生一个作用域。这俩是相绑定的。那作用域到底是什么呢?

我们都知道每一个对象都可以有属性,有方法。这是对象的两大特性,用来存值得。既然对象有属性,那一切为对象的东西就都可以有属性。对吧,典型的三段论嘛

function qwer(){

}

上边定义了一个函数,函数它也是一种特殊的对象,他身上也有属性。比如我们可以访问的qwer.name

 还有一些属性:

以上这些能看到的属性都是我们可以访问的,但是还有一些属性我们不能访问到,我们是看不到的,比如说test.[[scope]]属性。在计算机专业术语中,scope翻译过来就是域,区域的意思。[[scope]]属性仅供Javascript引擎使用,我们无法使用。test.[[scope]]里边存的就是由函数产生而产生的作用域。里边很复杂的结构,接下来慢慢讲解。

其实呢,[[scope]]里存的是执行期上下文集合,这个集合呈链式连接,我们把这种链式连接称为作用域链。到这可能就有点懵,一个函数在执行时只会有一个自己的执行期上下文(也就是上一节我们说的AO)啊,怎么能形成链了呢?又是跟谁形成了链呢?。我们还是看一个实例。

复制代码

function a() {
      console.log(b);
      function b() {
          console.log(a);
          var b = 234;
          console.log(b);
       }

       var aaa = 123;
       b();
}
var glob = 100;
a();

复制代码

看上边这段代码,在全局里,首先有一个a函数定义(不要管函数内部的语句),有一个glob变量声明与赋值,接着有一个a函数执行。

在这个a函数刚出生的时候,就已经有了自己的属性了。这时我们就可以访问a.name了。那么同时,肯定也有了[[scope]]属性了。那么这时[[scope]]属性里存的是啥呢?       

         

      图1.a函数定义时a.[[scope]]的属性值

因为a刚刚出生时的环境就是全局,所以这时[[scope]属性中只存有一位(第0位)GO,还没有达到链式的结构。此时的关系:

            图2.a函数定义时a.[[scope]]属性的内部关系

接下来a函数的执行,执行的时候会产生一个自己的AO,这时[[scope]]属性里的第0位就被自己的AO所占领了,而刚刚第0位的GO就被移到了第1位。

        图3.a函数执行时a.[[scope]]的属性值

 此时的关系如下:

 

          图4.a函数执行时a.[[scope]]属性内部关系

在a函数执行的时候产生了b函数的定义,所以b刚刚出生时的环境就是a函数,所以他拥有a的所有劳动成果。b函数定义时的关系:

    图5.b函数定义时[[scope]]属性内部关系 

紧接着b函数的执行,在执行时(或者执行的前一刻),b函数也会产生自己的AO,同样[[scope]]属性里的第0位就被自己的AO所占领了。这时的关系图:

              图6.b函数执行时[[scope]]属性的内部关系

而我们在哪个函数查找变量就到系统哪个函数的作用域链最顶端(第0位)依次往后开始查找。

所以在a函数当中访问b变量的时候,系统会在a执行时a的作用域链中找b变量(如图4),在a.[[scope]]的第0位(a的AO中)找到了b,所以打印b的结果为就为:function b(){......}。

b函数中访问a变量时,系统会到b执行时b的作用域链中找a变量(如图6),发现b.[[scope]]的第0 位(b的AO中)没有a变量,系统会继续找b.[[scope]]的第二位...,以此往下,在第三位找到了a变量,打印a就为:function a(){......}。

b函数中访问b变量,系统会到b执行时b的作用域链中找a变量(如图6),发现b.[[scope]]的第0 位(b的AO中)有b变量,直接打印结果为:234。

运行结果:

 

这就是我们的作用域,了解了这个执行过程,往下就可以更好的去理解闭包了,下次我们讲解闭包

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值