摘要:根据顺序我们也可以看出来,想要理解作用域链,执行上下文是我们碰到的第一个坎。
在我们前面理解了作用域之后,“作用域链”这个概念就产生了。那么作用域链是什么意思,它又是怎么形成的,跟哪些概念有关系,这就是我接下来几章想和大家探讨的内容:执行上下文、变量对象和作用域链。根据顺序我们也可以看出来,想要理解作用域链,执行上下文是我们碰到的第一个坎。
这一章我们就来讨论一下到底什么是执行上下文。
1. 定义当 JS 引擎开始执行预编译生成的代码时,就会进入到一个执行上下文(Executable Code - 简称 EC)。
在 ECMA 标准规范里并没有从技术角度去定义 EC 的具体类型和结构,这个是在实现 ECMAScript 引擎时需要考虑的问题。
但是在逻辑上,我们可以将活动的执行上下文看成一个栈结构。栈底部永远是全局上下文(global context),而顶部就是当前活动的执行上下文。执行到当前代码时,上下文入栈,执行完毕后,上下文出栈。
2. 可执行代码有几种前面说到当引擎执行到可执行代码的时候,就会将当前上下文压入上下文栈中。那么可执行的代码又分为几种?
在这里,我们先假设定义执行上下文栈是一个数组:
EC = [];
第一种可执行代码 -- 全局代码:
全局类型代码是在加载外部的 js 文件或者本地 标签中的代码。
注意,在全局代码中,并不包含定义在全局环境 function 内的代码。
程序启动后进入初始化全局环境:
EC = [ globalContext ];
第二种可执行代码 -- 函数代码:
当定义的函数被执行时,就进入了函数代码,当前函数上下文被压入 EC 栈中。
注意,在函数代码中,也不包含定义在该函数内部环境 function 内的代码。
例如:
var a = 10; function foo () { var b = 20; foo(); } foo();
这个例子中的 EC 是什么样子的呢?
// 初始化 EC = [ globalContext ]; // 第一次调用 foo 函数 EC = [functionContext, globalContext ]; // 在 foo 内递归调用自己 EC = [ functionContext - recursively, functionContext, globalContext ]; // 继续递归调用自己 EC = [ ...... functionContext - recursively2, functionContext - recursively, functionContext, globalContext ]; // 递归会不断调用下去,因为没有结束条件,所以这是一个死循环 // 所以,EC 只会不断增加新的上下文,但是却不会退出
只有每次 return 的时候,才会退出当前执行上下文,相应上下文会从栈中弹出,栈指针会自动移动位置。
注意,当函数没有明确指明 return 什么的时候,默认 return undefined 。
如果有抛出的异常没有被截获的话,也有可能从一个或多个执行上下文中退出。当所有代码执行完以后,EC 中只会包含全局上下文(global context),当程序退出以后,全局上下文也会退出。
第三种可执行代码 -- eval 代码:
eval 函数在调用的时候会产生上下文。
例如:
eval("var a = 10"); (function foo () { eval("var b = 20"); }()); alert(a); // 10 alert(b); // ReferenceError,b is not defined
这个例子中 EC 的变化如下:
// 初始化 EC = [ globalContext ]; // eval("var a = 10"); EC = [ evalContext, globalContext ]; // eval 执行完毕 EC = [ globalContext ]; // 立即执行函数 foo EC = [functionContext, globalContext ]; // eval("var b = 20"); EC = [ evalContext, functionContext, globalContext ]; // eval 执行完毕 EC = [ functionContext, globalContext ]; // foo 执行完毕 EC = [ globalContext ];
这就是一个典型的逻辑调用上下文栈。
在 setTimeout 和 setInterval 函数中的第一个参数也可以传入代码字符串,但是这个一般不会这么去用,所以这里也就不讨论了。
3. 结论执行上下文环境是我们了解变量对象和作用域链的基础,大家一定要好好理解(其实也并不难),下一节我们来讨论变量对象,相信会让大家有一定的收获。
欢迎关注我的公众号文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/81776.html
摘要:实现可伸缩的图片墙中文指南作者简介是推出的一个天挑战。现在你看到的是这系列指南的第篇。完整指南在从零到壹全栈部落。实现效果点击任意一张图片,图片展开,同时从图片上下两方分别移入文字。 Day05 - Flex 实现可伸缩的图片墙 中文指南 作者:©liyuechun 简介:JavaScript30 是 Wes Bos 推出的一个 30 天挑战。项目免费提供了 30 个视频教程、30 ...
摘要:关于点击进入项目是我于开始的一个项目,每个工作日发布一道面试题。即使这个时间周期内,小明取得多次满分。创建作用域链在执行期上下文的创建阶段,作用域链是在变量对象之后创建的。这种一层一层的关系,就是作用域链。 关于【Step-By-Step】 Step-By-Step (点击进入项目) 是我于 2019-05-20 开始的一个项目,每个工作日发布一道面试题。每个周末我会仔细阅读大家的答...
摘要:关于点击进入项目是我于开始的一个项目,每个工作日发布一道面试题。即使这个时间周期内,小明取得多次满分。创建作用域链在执行期上下文的创建阶段,作用域链是在变量对象之后创建的。这种一层一层的关系,就是作用域链。 关于【Step-By-Step】 Step-By-Step (点击进入项目) 是我于 2019-05-20 开始的一个项目,每个工作日发布一道面试题。每个周末我会仔细阅读大家的答...
摘要:介一回聊状态模式,官方描述允许一个对象在其内部状态改变时改变它的行为。有限状态机有限状态机是一个非常有用的模型,可以模拟世界上大部分事物。这个是官方说法,简单说,她有三个特征,状态总数是有限的。,任一时刻,只处在一种状态之中。 本回内容介绍 上一回聊了聊组合模式(Composite),用组合模式模拟了个图片库,聊了递归。介一回聊状态模式(State),官方描述允许一个对象在其内部状态改...
阅读 2630·2023-04-25 15:22
阅读 2806·2021-10-11 10:58
阅读 976·2021-08-30 09:48
阅读 1791·2019-08-30 15:56
阅读 1713·2019-08-30 15:53
阅读 1064·2019-08-29 11:16
阅读 1035·2019-08-23 18:34
阅读 1620·2019-08-23 18:12