JavaScript基础专题之执行上下文和执行栈(二)
执行顺序
一般执行顺序很显然按照创建顺序执行,对大对数开发者来说并不陌生。
像是这样:
foo(); // 报错
var foo = function () {console.log('foo1');}foo(); // foo1var foo = function () {console.log('foo2');}foo(); // foo2
复制代码
然而有的时候会是这样:
foo(); // foo2function foo() {console.log('foo1');}foo(); // foo2function foo() {console.log('foo2');}foo(); // foo2
复制代码
我们可以看到,作为函数调用的时候,会出现三个foo2。其实 JavaScript 引擎并非一行一行
地分析和执行程序,在执行之前会对一些对结构进行分析执行。比如第一个例子中的变量提升,和第二个例子中的函数提升。 那么JS又是如何进行结构化的解析的呢?执行过程中又做了什么动作呢?
栈
栈又是什么?
这张图分别展示了栈、堆和队列,其中栈就是我们所说的执行上下文栈
;堆是用于存储复杂类型
比如:对象,数组等等。队列就是异步队列,用于事件循环(event loop)
的执行。 JS代码在引擎中是以代码片段的方式来分析执行的,而并非一行一行来分析执行。
简单的例子
//入栈过程
Stack.push("chris")Stack.push("james")Stack.push("kobe")//出栈过程Stack.pop() //["chirs","james"]Strack.pop() //["chirs"]Stack.pop() //[]
复制代码
可以看出,栈是执行过程是一个先入后出的过程。
可执行代码
而这些代码片段的可执行代码无非为三种:全局代码(Global code)
、函数代码(Function Code)
、eval代码(Eval code)
。 这些可执行代码在执行的时候又会创建一个一个的执行上下文(Execution context)。例如,当执行到一个 函数的时候,JS引擎会做一些“准备工作”,而这个“准备工作”,我们称其为执行上下文
。 那么随着我们的执行上下文数量的增加,JS引擎又如何去管理这些执行上下文呢?这时便有了执行上下文栈
。
执行上下文栈
问题来了,我们写的函数多了去了,如何管理创建的那么多执行上下文呢?
所以 JavaScript 引擎创建了执行上下文栈(Execution context stack,ECS)来管理执行上下文
为了模拟执行上下文栈的行为,让我们定义执行上下文栈是一个数组:
Stack= [];
复制代码
试想当 JavaScript 开始要解释执行代码的时候,最先遇到的就是全局代码,所以初始化的时候首先就会向执
行上下文栈压入一个全局执行上下文,我们用 globalContext 表示它,并且只有当整个应用程序结束的时候,
Stack才会被清空,所以程序结束之前, Stack最底部永远有个 globalContext:
Stack = [globalContext// 一开始只有全局上下文
];
复制代码
一个简单的例子:
function fun3() {console.log('fun3')
}function fun2() {fun3();
}function fun1() {fun2();
}fun1();
复制代码
每当一个函数执行,就会创建一个执行上下文,并且压入执行上下文栈,当函数执行完毕的时候,就会将函
数的执行上下文从栈中弹出。
// fun1()
Stack .push(<fun1> functionContext);
//[globalContext,<fun1> functionContext]// fun1中有fun2,还要创建fun2的执行上下文
Stack .push(<fun2> functionCofuntext);
//[globalContext,<fun1> functionContext,<fun2> functionCofuntext],// fun2还调用了fun3
Stack .push(<fun3> functionContext);
//[globalContext,<fun1> functionContext,<fun2> functionCofuntext,<fun3> functionContext] // fun3执行完毕
Stack .pop();
//[globalContext,<fun1> functionContext,<fun2> functionCofuntext]// fun2执行完毕
Stack .pop();
//[globalContext,<fun1> functionContext]// fun1执行完毕
Stack .pop();
//[globalContext]// javascript接着执行下面的代码,但是Stack 底层永远有个globalContext
复制代码
一个复杂的例子:
var scope = "global scope";
function checkscope(){var scope = "local scope";function f(){return scope;}return f();
}
checkscope();
复制代码
var scope = "global scope";
function checkscope(){var scope = "local scope";function f(){return scope;}return f;
}
checkscope()();
复制代码
两段代码执行的结果一样,但是两段代码究竟有哪些不同呢?
答案就是执行上下文栈的变化不一样。
先模拟第一段代码:
Stack.push(<checkscope> functionContext);
Stack.push(<f> functionContext);
Stack.pop();
Stack.pop();
复制代码
再模拟第二段代码:
Stack.push(<checkscope> functionContext);
Stack.pop();
Stack.push(<f> functionContext);
Stack.pop();
复制代码
我们可以发现二三部分出栈和入栈是不同的。
总结
- JS代码在引擎中是以
一段一段
的方式来分析执行的,而并非一行一行
来分析执行 - 可执行代码分为三种:
全局代码(Global code)
、函数代码(Function Code)
、eval代码(Eval code)
,其中全局代码
、函数代码
比较常见,关于eval代码
可参考JavaScript 为什么不推荐使用 eval? - 每遇到
函数执行
的时候,就会创建一个执行上下文
,执行上下文
会进入执行上下文栈
中 - 程序开始最先入栈和程序结束最后出栈的都是
全局执行上下文
JavaScript基础专题系列
JavaScript基础专题系列目录地址:
JavaScript基础专题之原型与原型链(一)
JavaScript基础专题之执行上下文和执行栈(二)
新手写作,如果有错误或者不严谨的地方,请大伙给予指正。如果这篇文章对你有所帮助或者有所启发,还请给一个赞,鼓励一下作者,在此谢过。
转载于:https://juejin.im/post/5d0907cbe51d455a68490b7b
JavaScript基础专题之执行上下文和执行栈(二)相关推荐
- web前端知识集合——javascript基础篇之常量和变量(二)
3. 变量和常量: 1.1 变量的声明: js三种方式声明变量,声明不赋值时,默认值为underfined. (1)var声明:var name='Ace',同时声明多个变量var a=1,b=2,c ...
- Javascript执行上下文和执行栈
什么是执行上下文? 执行上下文就是当前JavaScript代码被解析和执行时所在环境的抽象概念,JavaScript中运行任何的代码都是在执行上下文. 什么是执行栈? 执行栈,在其他编程语言中也被叫做 ...
- 前端面试知识点总结JavaScript基础之原型和原型链(二)
一.JavaScript基础 原型和原型链 1.理解原型设计模式以及JavaScript中的原型规则 设计模式 1.工厂模式:在函数内建立一个对象,给对象赋予属性及方法再将对象返回设计模式. func ...
- JavaScript基础之立即执行函数
在JavaScript中有时候看到一些很神奇的函数比如下面截图: 这种函数只要浏览器加载的时候会自动运行,而需要调用,前面在闭包的时候也说过这种函数,一般将其称之为:立即执行函数. 立即函数的特征: ...
- 前端进击的巨人(一):执行上下文与执行栈,变量对象
写在开篇 已经不敢自称前端小白,曾经吹过的牛逼总要一点点去实现. 正如前领导说的,自己喝酒吹过的牛皮,跪着都得含着泪去实现. 那么没有年终完美总结,来个新年莽撞开始可好. 进击巨人系列开篇,不忘初心, ...
- 前端进击的巨人(1):执行上下文与执行栈,变量对象
(给前端大全加星标,提升前端技能) 作者:以乐之名 https://segmentfault.com/a/1190000017890535 写在开篇 已经不敢自称前端小白,曾经吹过的牛逼总要一点点去实 ...
- 2.JS执行上下文和变量对象
文章目录 执行上下文栈 函数上下文 变量对象 执行过程 进入执行上下文 代码执行 两个例子 1 2 JS 是单线程语言,因此执行顺序是顺序执行,不过 JS 引擎在执行 JS 代码的时候并不是逐行执 ...
- web前端知识集合——javascript基础篇之javascript背景历史和运行环境(一)
前言:温故而知新,可以为长也!万变不离其宗,无论是现在web前端技术衍生出多么优秀,好用的框架,插件,都离不开这门语言的基础知识.掌握各种优秀的框架,插件,只是"善用工具的人",深 ...
- Javascript中你必须理解的执行上下文和调用栈
执行上下文在 JavaScript 是非常重要的基础知识,想要理解 JavaScript 的执行过程,执行上下文是你必须要掌握的知识.否则只能是知其然不知其所以然. 理解执行上下文有什么好处呢? 它可 ...
- 了解Javascript中的执行上下文和执行堆栈
By Sukhjinder Arora | Aug 28, 2018 原文 如果你是或者你想要成为一名js开发者,那么你必须了解js程序内部的运作.理解执行上下文和执行堆栈对于理解js的其它概念(如提 ...
最新文章
- JS如何捆绑TypeScript声明文件
- String字符串类的获取功能
- alert,confirm和prompt
- 获取2个地址之间的距离(高德API)
- 多款主流编程语言,哪款开发软件最安全?
- html 存储登录状态,Vue中保存用户登录状态实例代码
- 禁用F12和鼠标右键,防止查看控制台代码
- Bootstrap 折叠插件Collapse 调用方式
- oracle数据库看开销,【Database】AIX系统下跟踪开销大的Oracle数据库进程
- 广二师的计算机专业好不,广东技术师范学院和广东第二师范学院哪一个更好?...
- 黄峥辞任董事长,超级投票权失效!拼多多已成为中国电商第一
- 比亚迪汽车发布品牌全新标识 取消了椭圆型边界
- [知识整理]Linux系统WIFI知识的一些整理
- git的SSH上传方式
- 线性布局LinearLayout(二)小练习
- PHP endif、endwhile、endfor、冒号、switch、foreach使用介绍、Heredoc 、Nowdoc
- 融合VOI与VDI、IDV、RDS,实现弹性的应用
- ts无损剪辑合并_软购团荐丨视频无损极速分割、合并、拼接。 处理视频比你想的更简单!...
- keras构建卷积神经网络
- 2021年第一季度中国电竞行业网络关注度分析报告