执行上下文对象的原理及使用

 执行上下文对象:
在浏览器执行javascript代码之前,浏览器会做一些准备工作(从准备工作这一操作开始,直到对应的这一作用域的所有代码被执行完,这样的一个过程就叫做执行上下文;执行上下文可以被看成一个对象,这个对象
就是用来管理其对应作用域中的各个数据,这些数据就是对象中的属性).

一. 全局作用域中的一些准备工作
    1. 找到标记的全局变量,并为其赋值为undefined;
    2. 给this赋值为window对象
    3. 函数声明,并给函数赋值为整个函数块

二. 函数作用域中的一些准备工作
    1. 找到标记的局部变量,并为其赋值为undefined;
    2. 给this赋值为window对象;
    3. 函数声明,并给函数赋值为整个函数块;
    4. 给参数赋值; (管理参数的数组对象)arguments赋值;
    5. 确定自由变量的取值作用域,并给自由变量赋值;
   
    由上面几点看出: 
    1. 函数被定义的时候,就确定了函数体内部变量的作用域;
    2. 函数每被调用一次,就会产生一个新的执行上下文对象,因为不同的调用会有不同的参数;

三. 全局执行上下文对象的数据内容:
    全局变量如:var a=10 或 函数表达式如:var fn={}     :    声明(默认值为undefined)

    函数声明如:function fun() {}    :   给这个函数赋值为整个函数块

    this   :    赋值为window对象


四. 局部(函数)执行上下文对象的数据内容:
    全局变量如:var a=10 或 函数表达式如:var fn={}     :    声明(默认值为undefined)

    函数声明如:function fun() {}    :   给这个函数赋值为整个函数块

    this   :    赋值为window对象
   
    参数   :    赋值(传进来的值)

    arguments    :   赋值(参数的值,未传实参时,赋空值)

    自由变量的取值作用域   :   找到自由变量的作用域,并赋值


五. 执行上下文栈
    执行全局代码时,会产生一个全局上下文环境(压栈),每调用全局中的一个函数时,又会产生一个函数上下文环境,当函数调用完成时,这个函数上下文环境被销毁(出栈),在重新回到全局上下文环境.处于活动状态的上下文环境始终只有一个,这就是压栈和出栈的过程.
   
    例:  var a = 10;  //进入全局上下文环境
         var fn = function(y){
             var c = 5;
             console.log(y + c);
         };
         var bar = function(x){
             var b = 5;
             fn(x + b); //进入fn函数上下文环境
         };
         bar(10); //进入bar函数上下文环境

        解析:
        1. 在执行代码之前,首先创建全局上下文环境,此时各个变量的状态为:
                       全局变量a     undefined
                       全局变量fn    undefined
                       全局变量bar   undefined
                       this         window对象
  
        2. 创建全局上下文环境后,开始从上到下依次执行,当读到bar()这句时,前面的全局上下文环境中的变量都被赋值,此时的状态为:
                       全局变量a     10
                       全局变量fn    function
                       全局变量bar   function
                       this         window对象

        3. 调用bar函数时(即读bar(10)这条语句),进入函数内部,在执行函数体内部语句之前,创建一个新的该函数作用域的上下文环境,把这个上下文环境压栈,设置为活动状体,此时的状态为:(bar函数的上下文环境)
                       局部变量b     undefined
                              x     10
                      arguments     [10]
                           this     window对象

         4. 创建bar的上下文环境后,开始从上到下依次执行bar内的代码,当读到fn(x+b)时,前面的bar的上下文环境中的变量都被赋值,此时的状态为:
                       局部变量b     5
                              x     10
                      arguments     [10]
                           this     window对象
       
         5. 调用fn()函数时(即读fn(x + b)这条语句),进入函数内部,在执行函数体内部语句之前,创建一个新的该函数作用域的上下文环境,把这个上下文环境压栈,设置为活动状体,此时的状态为:(fn函数的上下文环境)
                       局部变量c     undefined
                              y     15(x+b)
                      arguments     [15]
                           this     window对象

      
         6. 当fn函数的上下文环境执行完后,fn的上下文环境被销毁,删除这个上下文环境的所有数据,也就是出栈;此时重新回到bar函数的上下文环境;
         
         7. 当bar函数的上下文环境执行完后,bar的上下文环境被销毁,删除这个上下文环境的所有数据,也就是出栈;此时重新回到全局作用域的上下文环境,直到所有代码执行完毕.

         

六. 作用域和执行上下文的关系
    1. 在代码中,除了全局作用域外,每个函数都会创建自己的作用域;
    2. 作用域是在函数被定义的时候就确定的,而不是在调用时被确定的;
    3. 作用域只是一个抽象的概念,其中并没有变量,需要通过作用域对应的上下文环境来获取变量的值;
    4. 在同一个作用域下,每次的调用,都会产生不同的上下文环境,当然就会产生不同的变量的值(即使值一样,所在的内存区域却不一样)
    例: (这个例子没看出哪里体现了上面的第2点)
        var a = 10, b = 20;
        function fn(x){
            var a = 100, c = 300;
            function bar(x){
                var a = 1000, d = 4000;
                console.log(a + " " + d);
            }
            bar(100);
            bar(200);
        }
        fn(10);



七. 自由变量
    1. 概念: 在作用域A中,使用了变量X,但并没有在A作用域中声明(即在其他作用域声明的变量X),对于作用域A来说,X就是一 个自由变量.
    例: var X = 10;
        function fn(){
           console.log(X); //这里的X就是一个自由变量
        }

八. 作用域链(这里用变量X举例来说明)
    1. 先在当前所在的作用域查找变量X,如果有,则获取,如果没有,则向当前作用域的上一级继续查找,如果找到,则获取那一级的值;如果还是没有,一直查找到全局作用域;
    2. 如果继续查找到当前的作用域为全局作用域,却还没有找到时,则表示变量X为定义,结束;
    3. 不是全局作用域,那就是函数作用域.

                       
           
    
    

转载于:https://www.cnblogs.com/Hrbacity/p/4820650.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值