JavaScript 之作用域和作用域链

1、[[scope]]:每个JavaScript函数都是一个对象,对象的有些属性我们可以访问,有些不可以,这些属性仅供引擎存取,其中[[scope]]就是其中一个。[[scope]]值得是我们所说的作用域,存储了运行期上下文集合(执行期上下文(AO GO)见https://blog.csdn.net/gxgalaxy/article/details/88729727)。

2、作用域链:[[scope]]中存储的执行期上下文对象的集合,集合呈链式连接,这就叫作用域链。

我们以下面函数为例:

function a(){
  function b(){
    var b = 234; 

  }
  var a = 123;
  b();
}
var glob = 100;
a();
// a defined-->a.[[scope]]-->0:GO{}
// a doing     a.[[scope]]-->0:AO{}
                         //  1:GO{}

当a函数被定义的时候产生全局执行期上下文GO:

当a函数被执行的时候产生自己的执行期上下文AO:这个时候a的AO会放在作用域链的顶端

由于a的执行产生了b函数的定义,b作为一个函数也有自己的[[scope]],当b出生的时候,他的环境是a给的,所以:

b被创建的时候发生的过程:

b在执行的时候,也生成自己的执行期上下文放在作用域链的顶端:

在b中寻找变量的时候,从作用域链的顶端往下找。

该过程中存在的疑问:

1、b执行过程中a的AO是否和a的AO相同:我们采用改变b函数中的aa,再在a中访问aa来判断两者是否相同。

function a(){
  function b(){
    var bb = 234; 
    aa = 0;

  }
  var aa = 123;
  b();
  console.log(aa);
}
var glob = 100;
a();

运行结果 aa = 0,说明两者是同一个。

2.当a执行完被销毁以后,a回到被执行前,此时b也消失。

例题:

function a(){
  function b(){
    function c(){

    }
    c();
  }
  b();
}                         
a();
//定义和执行过程中作用域的变化
a defined a.[[scope]]-->0:GO
a doing   a.[[scope]]-->0:aAO
                        1:GO

b defined b.[[scope]]-->0:aAO
                        1:GO
b doing   b.[[scope]]-->0:bAO
                        1:aAO
                        2:GO

c defined c.[[scope]]-->0:bAO
                        1:aAO
                        2:GO
c doing   c.[[scope]]-->0:cAO
                        1:bAO
                        2:aAO
                        3:GO

注意:a函数不执行,b函数也不能被定义。每次执行完都会回到被定义的状态。

猜你喜欢

转载自blog.csdn.net/gxgalaxy/article/details/88799387