美文网首页工作生活
前端基础查漏补缺(二):执行上下文

前端基础查漏补缺(二):执行上下文

作者: AizawaSayo | 来源:发表于2019-07-03 13:12 被阅读0次

每次当控制器转到可执行代码的时候,就会进入一个执行上下文。执行上下文可以理解为当前代码的执行环境,它会形成一个作用域。JavaScript中的运行环境大概包括三种情况。

  • 全局环境:JavaScript代码运行起来会首先进入该环境
  • 函数环境:当函数被调用执行时,会进入当前函数中执行代码
  • eval(不建议使用,可忽略)

因此在一个JavaScript程序中,必定会产生多个执行上下文,JavaScript引擎会以栈的方式来处理它们,这个栈我们称其为函数调用栈(call stack)。栈底永远都是全局上下文,而栈顶就是当前正在执行的上下文。
当代码在执行过程中,遇到以上三种情况,都会生成一个执行上下文,放入栈中,而处于栈顶的上下文执行完毕之后,就会自动出栈。为了更加清晰的理解这个过程,根据下面的例子,结合图示给大家展示。

执行上下文可以理解为函数执行的环境,每一个函数执行时,都会给对应的函数创建这样一个执行环境。

var color = 'blue';

function changeColor() {
    var anotherColor = 'red';

    function swapColors() {
        var tempColor = anotherColor;
        anotherColor = color;
        color = tempColor;
    }

    swapColors();
}

changeColor();

我们用ECStack来表示处理执行上下文组的堆栈。第一步,首先是全局上下文入栈,全局上下文中的可执行代码开始执行。遇到了changeColor(),这一句激活函数changeColor创建它自己的执行上下文,因此第二步就是changeColor的执行上下文入栈。接着控制器开始执行changeColor中的可执行代码,遇到swapColors()之后又激活了一个执行上下文。因此第三步是swapColors的执行上下文入栈。在swapColors的可执行代码中,再没有遇到其他能生成执行上下文的情况,因此这段代码顺利执行完毕,swapColors的上下文从栈中弹出。继续执行changeColor的可执行代码,也没有再遇到其他执行上下文,changeColor顺利执行完毕之后弹出。这样,ECStack中就只身下全局上下文了。全局上下文在浏览器窗口关闭后出栈。


上例图示

详细了解了这个过程之后,我们就可以对执行上下文总结一些结论了。

  • 单线程
  • 同步执行,只有栈顶的上下文处于执行中,其他上下文需要等待
  • 全局上下文只有唯一的一个,它在浏览器关闭时出栈
  • 函数的执行上下文的个数没有限制
  • 每次某个函数被调用,就会有个新的执行上下文为其创建,即使是调用的自身函数,也是如此。

为了巩固一下执行上下文的理解,我们再来绘制一个例子的演变过程,这是一个简单的闭包例子。

function f1(){
    var n=999;
    function f2(){
        alert(n);
    }
    return f2;
}
//var result1=f1;  //result得到的是f1函数本身的定义
var result=f1();//得到的是f1函数运行后的结果返回了f2函数
//result1(); //等于f1();
result(); //运行等于f2();   因此结果是999

全局上下文执行,f1()的执行结果赋值给result,也就是f1被调用,生成了f1的执行上下文(入栈)。接下来result得到了f2方法(引用地址)。执行result()时创建了一个新的上下文,被调用的是f2的引用而不是f2。具体演变过程如下。


上例执行顺序

练习脑补下这个例子的上下文执行顺序

var name = "window";
var p = {
    name: 'Perter',
    getName: function() {
    // 利用变量保存的方式保证其访问的是p对象
        var self = this;
        return function() {
            //return this.name;
            return self.name;
        }
    }
}
var getName = p.getName();//p.getName()被调用。执行结果是定义了self的值为p对象,里面的self.name就锁死成Peter了。
//把function(){ return self.name; }函数赋给了全局变量getName。p.getName()出栈。
var name_ = getName();//getName调用,入栈。出栈。执行结果赋给name_;
//因此如果方法里是return this.name是被全局调用,值就是window了。
console.log(name_);

参考文章出处:前端基础进阶(二):执行上下文详细图解

相关文章

  • 前端基础查漏补缺(二):执行上下文

    每次当控制器转到可执行代码的时候,就会进入一个执行上下文。执行上下文可以理解为当前代码的执行环境,它会形成一个作用...

  • 从新开始

    安卓、前端。从新开始,查漏补缺。

  • 【Android面试查漏补缺】之事件分发机制详解

    前言 查漏补缺,查漏补缺,你不知道哪里漏了,怎么补缺呢?本文属于【Android面试查漏补缺】系列文章第一篇,持续...

  • 查漏补缺二

    摘录 只供自己学习 1.typeof 和 __typeof,typeof 的区别? 2.谈谈对UIResponde...

  • 前端基础进阶系列

    前端基础进阶(一):内存空间详细图解前端基础进阶(二):执行上下文详细图解前端基础进阶(三):变量对象详解前端基础...

  • PHP 基础查漏补缺

    1、注释的第三种写法 使用#,这是shell风格的写法。 2、PHP 不像许多其他的编程语言,它不支持全局变量(除...

  • 基础英语-查漏补缺

    关于Hope的用法的易错点 1. hope的被动语态中多用it作为形式主语 eg. It is hoped tha...

  • python查漏补缺-基础

    最近刷题感觉一些简单的概念看似很熟悉,实际上还有很多旮旯需要掌握,本篇不做笼统的汇总,仅针对一些易混淆概念之间的区...

  • iOS知识体系

    iOS 的知识体系,包括了基础、原理、应用开发、原生与前端四大模块。 根据下面的体系框架图,慢慢查漏补缺吧

  • 查漏补缺

    如果想让HTML5标签兼容低版本浏览器的话,可以使用 html5shiv js来实现。注意:一定要把它引入到前面。...

网友评论

    本文标题:前端基础查漏补缺(二):执行上下文

    本文链接:https://www.haomeiwen.com/subject/gbifhctx.html