作用域

作用域指[[scope]]每个js函数都是一个对象,对象中有些属性我们可以访问但有些不可以,这些属性仅供js引擎存取,[[scope]]就是其中一个。

[[scope]]指的就是我们所说的作用域,作用域里面存储了运行期上下文的集合

作用域链

作用域链指[[scope]]中所存储的执行期上下文对象的集合,这个集合呈链式链接,所以我们把这种链式链接叫做作用域链.

运行期上下文

当函数执行时的前一刻(预编译),会创建一个执行期上下文的内部对象。一个执行期上下文定义了一个函数执行时的环境,函数每次执行对应的执行上下文都是独一无二的,(每次执行都会创建一个AO)所以多次调用一个函数会导致创建多个执行上下文,当函数执行完毕,他所产生的执行上下文被销毁.

function test() {
    }
    test.[[scope]] 
//scope(域)里面存储的是作用域,这个是访问不了的
//每一个对象都有属性有方法
//函数也是一种对象(test.name=test),叫函数类对象
1
2
3
4
5
6
function a() {
    }
        var glob = 100;
        a(); 
1
2
3
4

1.当a函数定义时

a defined-->a.[[scope]]-->0 :GO{}

2.当a函数执行时

创建AO 会放到作用域链的顶端(第 0 位)

a doing-->a.[[scope]]-->0:AO{} 1:GO{}

查找变量:从作用域链的顶端依次向下查找

a会从作用域链的顶端去找 也就是0:AO{}去找



function a() {
            function b() {
                var bb = 234;
                aa = 0;
            }
            var aa = 123;
            b();
            console.log(aa)    
    //输出的是0 因为在b的作用域链b会先找自己的AO
        }
        var glob = 100;
        a();
1
2
3
4
5
6
7
8
9
10
11
12

a定义时,会有一个a.[[scope]] scope指向的是一个全局的执行上下文GO{} a被执行,会有一个a.[[scope]] scope指向的是最顶端AO{} 下来GO{}

b定义时,用的是a的劳动成果 a的AO{}和GO{} b执行时,会按自己的执行期上下文0.自己的AO 1.A的AO 2.全局的GO 去执行

b函数执行完后需要销毁自己的执行期上下文 b函数执行完也代表a函数执行完了 a函数执行完了也代表b函数没了

# 总结

function a() {
    function b() {
        function c() {
             }
        c();
    }
    b();
}
a();
1
2
3
4
5
6
7
8
9
    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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

作用域总结

在任何函数里面想访问变量就找它的作用域链(执行时doing),可以看出在外部的不能访问内部的变量,在里面的可以访问外部的变量,里面所有的aAO都是一个人,bAO都是一个人。

哪个函数先执行完 就销毁哪个