我们在JS学习初期或者面试的时候常常会遇到考核变量提升的思考题。比如先来一个简单一点的。

console.log(a);   // 这里会打印出什么?
var a = 20;

暂时先不管这个例子,我们先引入一个JavaScript中最基础,但同时也是最重要的一个概念执行上下文(Execution Context)。

每次当控制器转到可执行代码的时候,就会进入一个执行上下文。执行上下文可以理解为当前代码的执行环境,它会形成一个作用域。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的上下文从栈中弹出。

swapColors的执行上下文弹出之后,继续执行changeColor的可执行代码,也没有再遇到其他执行上下文,顺利执行完毕之后弹出。这样,ECStack中就只身下全局上下文了。

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

注意:函数中,遇到return能直接终止可执行代码的执行,因此会直接将当前上下文弹出栈。

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

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

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

function f1(){var n=999; function f2(){ alert(n); } return f2; } var result=f1(); result(); // 999 

因为f1中的函数f2在f1的可执行代码中,并没有被调用执行,因此执行f1时,f2不会创建新的上下文,而直到result执行时,才创建了一个新的。具体演变过程如下。

如果你在某公众号看到我的文章,然后发现下面的评论说最后一个例子错了,请不要管他们,他们把函数调用栈和作用域链没有分清楚就跑出来质疑,真的很有问题。建议大家读一读这系列的第六篇文章,教你如何自己拥有判断对错的能力。

最后留一个简单的例子,大家可以自己脑补一下这个例子在执行过程中执行上下文的变化情况。

var name = "window";var p = {name: 'Perter',getName: function() { // 利用变量保存的方式保证其访问的是p对象 var self = this; return function() { return self.name; } } } var getName = p.getName(); var _name = getName(); console.log(_name);

转载于:https://www.cnblogs.com/kdy11/p/8940727.html

前端基础进阶(二):执行上下文详细图解相关推荐

  1. jquery function_前端基础进阶(十三)详细图解jQuery扩展jQuery插件

    UI 鉴赏 早几年学习前端,大家都非常热衷于研究jQuery源码. 我至今还记得当初从jQuery源码中学到一星半点应用技巧的时候常会有一种发自内心的惊叹,"原来JavaScript居然可以 ...

  2. 前端基础进阶(七):函数与函数式编程

    纵观JavaScript中所有必须需要掌握的重点知识中,函数是我们在初学的时候最容易忽视的一个知识点.在学习的过程中,可能会有很多人.很多文章告诉你面向对象很重要,原型很重要,可是却很少有人告诉你,面 ...

  3. boost log 能不能循环覆盖_前端基础进阶(十四):深入核心,详解事件循环机制...

    Event Loop JavaScript的学习零散而庞杂,很多时候我们学到了一些东西,但是却没办法感受到进步!甚至过了不久,就把学到的东西给忘了.为了解决自己的这个困扰,在学习的过程中,我一直在试图 ...

  4. 前端基础进阶(十):面向对象实战之封装拖拽对象

    https://segmentfault.com/a/1190000012646488  https://yangbo5207.github.io/wutongluo/ 说明:此处只是记录阅读前端基础 ...

  5. 前端基础(二):CSS

    文章目录 一.CSS基础语法 二.CSS样式的引入方式 (1)内联(行内.行间)样式: (2)内部样式: (3)外部样式: 三.CSS中的颜色表示法 (1)单词表示法: (2)十六进制表示法: (3) ...

  6. 前端基础进阶之Promise

    前言 Promise的重要性我认为我没有必要多讲,概括起来说就是必须得掌握,而且还要掌握透彻.这篇文章的开头,主要跟大家分析一下,为什么会有Promise出现. 在实际的使用当中,有非常多的应用场景我 ...

  7. 前端基础进阶(十三):透彻掌握Promise的使用,读这篇就够了

    Promise的重要性我认为我没有必要多讲,概括起来说就是必须得掌握,而且还要掌握透彻.这篇文章的开头,主要跟大家分析一下,为什么会有Promise出现. 在实际的使用当中,有非常多的应用场景我们不能 ...

  8. 重温前端基础(二) 移动WEB开发

    目录 1. 移动端基础 2. 视口 2.1 meta标签 3. 二倍图 3.1 物理像素 & 物理像素比 3.2 背景缩放 background-size 4. 移动开发选择和技术解决方案 4 ...

  9. JS高级讲解面向对象,原型,继承,闭包,正则表达式,让你彻底爱上前端(进阶二)...

    JavaScript 高级 学习目标: 理解面向对象开发思想 掌握 JavaScript 面向对象开发相关模式 掌握在 JavaScript 中使用正则表达式 面向对象介绍 程序中面向对象的基本体现 ...

最新文章

  1. PHP通过header实现文本文件的下载
  2. ${pageContext.request.contextPath}
  3. 使用Spring和Hibernate进行集成测试有多酷
  4. Java中使用有返回值的线程
  5. java判断用户是否在某一个区域登录_单点登录实现原理
  6. openCV2.4.13+VS2015+Cmake开发环境配置,解决nonfree问题
  7. 河南理工大学计算机专业几本,2018河南理工大学是几本 是一本还是二本
  8. 读python源码--对象模型
  9. hdoj 1570 A C
  10. java上传视频并播放_javaweb中上传视频,并且播放,用上传视频信息为例
  11. docker 部署 shipyard
  12. 算法:去除英文文本中重复单词
  13. Lua Busted 单元测试简介(Windows 环境)
  14. 【程序源代码】微信小程序商城
  15. Android支持播mp4的文件管理,Android - 简单使用VideoView播放MP4
  16. nanotime java_Java System nanoTime()方法
  17. 英语思维导图大全 前言(一)
  18. 自然几何之分形(2)
  19. ORBSLAM源码理论分析2—单目初始化
  20. vue - weath

热门文章

  1. 液晶显示模块的分类和基本知识
  2. 几种字符串到byte[] 数组转化为String 的方法
  3. 【opencv学习】【图像的数值计算操作】
  4. Request中getContextPath、getServletPath、getRequestURI、request.getRealPath的区别
  5. 人工智能语言python实验报告_【报名】人工智能语言Python启蒙课程(五六年级)...
  6. Python —— 深拷贝和浅拷贝
  7. Ubuntu 16.04查看软件安装位置
  8. 波兰表达式 构建 表达式树
  9. P1807 最长路 (SPFA写法)
  10. json增加反斜杠 php_thinkphp5.1.x~5.2.x版本反序列化链挖掘分析