JavaScript笔记(三)

73 阅读3分钟

一、作用域([scope])

作用域存储了运行期上下文的集合,决定了代码区块中的变量和其他资源的可见性。

二、执行环境(execution context)

定义了变量或者函数有权访问的数据,决定了它们的行为。(存储了作用域链某个变量对象指向的变量或者数据的集合)JavaScript解释器初始化执行代码时,首先进入全局执行环境,每次调用函数时都会创建一个新的执行环境并将该执行环境压入执行环境栈的顶部,函数调用结束之后该函数的环境变量都会从执行环境栈中弹出并销毁,保存在其中的所有的变量和函数定义也随之销毁。

执行环境栈(Execution Context Stack):当执行进入一个函数时,函数的执行环境就会被推进一个栈中,而在函数执行完之后,栈将其执行环境移除,它里面的变量和数据会被标记和清除,等待垃圾回收,再把控制权返回给之前的执行。JavaScript程序中的执行正是由这个机制控制着。

三、作用域链(the scope chain)

当代码进入到某个执行环境,准备执行时,会为该执行环境对应的对象创建一个作用域链。作用域链其实相当于变量对象的集合,其第一个元素是当前执行环境的变量对象(Variable Object),最后一个时全局执行环境的变量对象(在浏览器中即window对象)。

四、执行期上下文(context)

上下文始终是this关键字的值,它是当前执行代码的对象的引用,取决于函数是如何被调用的。当一个函数被作为对象中的一个方法被调用的时候,该函数的this则被设置为调用该方法的对象。 定义在全局的函数this默认为全局上下文,在浏览器中它被指向window对象。

五、标识符解析

\color{#525252}{标识符:变量、函数、属性,或者函数的参数}
标识符解析是沿着作用域一级一级地搜索标识符的过程。搜索过程从上到下逐级地向后回溯直到找到标识符为止。

案例:、

Activation Object (AO):函数执行上下文;

Gobal Object(GO):全局执行上下文;

函数执行完,AO会被销毁,该函数的作用域链也会被释放,但是闭包会导致上级的执行上下文AO不会被释放(闭包本身执行完会释放自己的AO),因此会导致加载过慢或者内存泄漏,

    var a = 1;
    function test(){
        a = 3;
        console.log(a);
        test2();
        var b = 3;
        function test2(){
            var b = 4;
            console.log(b)
        }
    }
    test(1,2,3);

当test未被执行时,作用域存放着GO,函数定义时不会形成自己的AO:

当test()执行,形成自己的AO,并将该AO压入栈,函数test执行查找变量时从上到下逐级查找,比如执行到a=3时,先从test的AO开始查找,test中并没有定义a,则再从上一级查找,最终在Go找到变量a,并把它赋值为3:
当test2定义时,因为test2是test的内部函数,故它被定义时的执行上下文和test的执行上下文是一样的:
当test2执行时,test2中定义了b,故不会再向上查找变量:
当test2执行完,test2AO被销毁:
当test执行完:test的AO被销毁: