zoukankan      html  css  js  c++  java
  • JS底层知识理解之执行上下文篇

    JS底层知识理解之执行上下文篇

    一、什么是执行上下文(Execution Context)

      执行上下文可以理解为当前代码的执行环境,它会形成一个作用域。

    二、JavaScript引擎会以什么方式去处理多个EC

        答案:堆栈。

      堆栈底部永远都是全局上下文(Global Context),而顶部就是当前(活动的)执行上下文。堆栈在EC类型进入和退出上下文的时候被修改(推入或弹出)。

    //其实,这里可以将堆栈看作一个数组 
    ECStack = [];
    //数组的最后一项 
    ECStack[ECStack.length - 1] = 全局上下文;
    //数组的第一项 
    ECStack[0] = 当前的执行上下文;

    三、EC的分类

    1、全局EC

        JavaScript代码运行起来会首先进入该环境。

        全局代码是在"程序"级处理的:例如加载外部的js文件或者本地<script></script>标签内的代码,并不包括任何function体内的代码。

      【全局上下文只有唯一的一个,直到应用程序退出,保存在其中的所有变量和函数定义才会被销毁】

    //在初始化(程序启动)阶段,ECStack是这样的:
    ECStack = [
      globalContext
    ];

    2、函数EC

      当函数被调用执行时,会进入当前函数中执行代码;函数执行环境中的所有代码执行完毕后,该环境被销毁,保存在其中的所有变量和函数定义也随之销毁。

      当进入 function 函数代码(所有类型的funtions)的时候,ECStack 被压入新元素。

    tips:

    1、具体的函数代码不包括内部函数(inner functions)代码

    2、同步执行,只有栈顶的上下文处于执行中,其他上下文需要等待

    3、函数中,遇到 return语句 能直接终止 可执行代码(Execution Code) 的执行,因此会直接将 当前EC 弹出栈

    (类似于数组中的 shift() 方法,因为所弹出的当前EC是ECStack[0]);

    4、相关代码执行完以后,ECStack只会包含 全局上下文,一直到整个应用程序结束。

    5、每次某个函数被调用,就会有个新的执行上下文为其创建,即使是调用的自身函数,也是如此

    6、函数的执行上下文的个数没有限制

    // 例子
    (function foo(bar) { if (bar) { return; } foo(true); })(); // 第一次foo的激活调用 ECStack = [ <foo> functionContext, globalContext ]; // foo的递归激活调用 ECStack = [ <foo> functionContext – recursively(递归的意思), <foo> functionContext, globalContext ];

    四、EC的生命周期

      第一阶段:EC创建阶段

    1、创建变量对象(Variable Object)

    2、建立作用域链

    3、确定 this 的指向

      第二阶段:EC执行阶段

    1、变量对象转化为活动对象 (VO -----》AO)(只在函数环境下才有这个转化)

    2、变量赋值

    3、函数引用

    4、执行其他代码

    五、例子简析

    例1:

    var color = 'blue';
    
    function changeColor() {
        var anotherColor = 'red';
    
        function swapColors() {
            var tempColor = anotherColor;
            anotherColor = color;
            color = tempColor;
        }
    
        swapColors();
    }
    
    changeColor();

    EC的入栈出栈整个过程可以描述为:“先进后出,后进先出”。

    1、全局上下文入栈

    2、changeColor的执行上下文入栈

    3、swapColors的执行上下文入栈

    4、swapColors的执行上下文出栈

    5、changeColor的执行上下文出栈

    6、全局上下文在浏览器窗口关闭后出栈

    例2:

    function outer(){
        var n=999;
        function inner(){
            alert(n); 
        }
        return inner;
    }
    var result=outer();
    result(); // 999

    1、全局上下文入栈

    2、outer的执行上下文入栈

    3、outer的执行上下文出栈

    4、inner的执行上下文入栈

    5、inner的执行上下文出栈

    6、全局上下文在浏览器窗口关闭后出栈

     

    注意:因为 outer 中的函数 inner 在 outer 的可执行代码中,并没有被调用执行,因此执行 outer 时,inner 不会创建新的上下文,而直到 resul t执行时,才创建了一个新的执行上下文。

    参考博文:

      http://blog.csdn.net/pingfan592/article/details/55189804

      http://www.cnblogs.com/TomXu/archive/2012/01/13/2308101.html

  • 相关阅读:
    Win7 64位系统上Hadoop单机模式的安装及开发环境搭建
    HBase配置文件设置
    YARN HA 配置文件设置
    Hadoop的配置文件设置(HDFS HA)
    记一次java heap space的解决办法
    记一次sql优化——left join不走索引问题
    js黑魔法
    css坑了我一下下之line-height
    target-densitydpi=device-dpi会使其他ui插件布局变小
    redis缓存过期key优化-缓存不释放
  • 原文地址:https://www.cnblogs.com/Jm-jing/p/7325442.html
Copyright © 2011-2022 走看看