JavaScript:执行机制
在说本章主要讨论的问题之前,先来讲述一下函数中的try/catch/finally分别代表什么:
try:语句测试代码块的错误;
catch:只有当try中的代码块发生错误的时候,才会执行这部分的代码,参数err记录了try内代码块的错误信息;
finally:不管有无异常都会执行内部的代码
介绍完几个关键字代表的含义,我们接着来思考两个问题:
- try,catch,finally中return最终会返回谁的结果?
- finally中的代码是在 return之前执行,还是之后执行?
看下面的代码:
function func() {try {return 0;} catch (err) {console.log(err)} finally {console.log("a")}
}console.log(func());
上面代码中,我们执行函数func(),其打印的结果是什么呢?按照正常的逻辑捋捋,应该是先打印0再打印字符串a,但是结果恰恰相反,上面代码的执行结果是先打印a再打印0。显然,第二个问题我们已经有了答案。finally中的代码会在return语句之前执行。ok,我们再看一段代码:
function func() {try {return 0;} catch (err) {console.log(err)} finally {return 1}
}console.log(func());
这时,我们分别在try和finally中放置了return语句,最终的打印结果是1 ,所以上面提的第一个问题的答案就是最终会返回finally中的return结果,咋一看,是finally中有return,所以try和catch中的return语句被finally覆盖了,其实不然,第一个例子告诉我们了代码的执行顺序,finally中的return语句会先执行,而try和catch中的return语句没有在执行,所以最终结果是finally中的return语句。
综合上面的分析,我们可以得到以下几点结论:
- 在执行任何try和catch中的return语句之前,都会先执行finally中的代码;
- 如果finally中包含return语句,那么程序就会提前被return出来,所以不建议在finally中放置return语句;
- 编辑器内会把finally中的return表现为一个warning;
但是,这种执行方式不是很奇怪吗,它的执行方式跟大多数的开发逻辑不相同,导致这种局面的原因就是在于它的执行机制。这个机制的执行基础,就是基于JavaScript中语句的执行完成状态,它可以用一个标准类型来表示:Completion Record,它是用来描述异常或者跳出等语句的执行过程。Completion Record表示一个语句的执行完成后的结果,它有三个字段:
- [[type]]:表示完成的类型,通常有break,continue,return,throw以及normal几种类型;
- [[value]]:表示语句的返回值,如果语句没有,则返回empty;
- [[target]]:表示语句的目标,一般是一个JavaScript标签;
JavaScript 就是依赖Completion Record类型实现各种神奇的控制,下面介绍下使用Completion Record类型,控制语句执行的过程。先从网上抠到一张神图(有关语句的详细分类):
先说下普通语句,普通语句在JavaScript中就是指的不带控制能力的语句,这种语句的执行特点就是从前往后依次执行,在普通语句执行完毕之后,普通语句在执行后,就会得到[[type]]为normal的Completion Record类型,JavaScript引擎解析到的时候,就会继续执行下一条语句。
语句块就是指用大括号括起来的语句,它本质上是一种语句的复合结构,内部可以嵌套。当语句块的内部语句的Completion Record的[[type]]不为normal的话,会打断语句块的后续执行,例如:
{var i = 1 return i i++console.log(i)
}
// 其内部包含return的Completion Record类型,所以直接return 1,后面的语句不会执行
控制型的语句主要分为两部分:一是对其影响内部的,包括if、switch、while/for、try等等;二是对其外部造成影响的,包括break、continue、return、throw等等。这两类语句的配合可以产生控制代码的执行顺序和执行逻辑。
带标签的语句:任何 JavaScript 语句是可以加标签的,在语句前加冒号即可,同时还有就是类似于注释,基本没有任何用处,唯一有作用的时候是:与完成记录类型中的 target 相配合,用于跳出多层循环。
在这些语句中,只有表达式语句会产生 [[value]],当然,从引擎控制的角度,这个 value 并没有什么用处。
最后我们来解释下为什么在finally加入return语句后,为什么得到的结果为1?因为finally中的内容必须保证执行,所以try/catch执行完毕,即使得到的结果是非normal型的完成记录,也必须要执行finally。而当finally执行也得到了非normal记录,则会使finally中的记录作为整个try结构的结果。
JavaScript:执行机制相关推荐
- javascript执行机制
转自:ssssyoki 这一次,彻底弄懂 JavaScript 执行机制 在掘金上讲解js执行机制的文章,收获很多.故复制过来,做复习笔记用 不论你是javascript新手还是老鸟,不论是面试求职 ...
- JavaScript 执行机制
前端开发,一篇文章让你彻底搞懂,什么是JavaScript执行机制!:https://zhuanlan.zhihu.com/p/139261821 大白话讲解 JavaScript 执行机制,一看就懂 ...
- 宏事件、微事件、 JavaScript 执行机制
案例预热: setTimeout(function(){console.log('定时器开始啦')});new Promise(function(resolve){console.log('马上执行f ...
- js等待 callback 执行完毕_前端开发,一篇文章让你彻底搞懂,什么是JavaScript执行机制!...
不论你是javascript新手还是老鸟,不论是面试求职,还是日常开发工作,我们经常会遇到这样的情况:给定的几行代码,我们需要知道其输出内容和顺序.因为javascript是一门单线程语言,所以我们可 ...
- 这一次,彻底弄懂 JavaScript 执行机制
本文的目的就是要保证你彻底弄懂javascript的执行机制,如果读完本文还不懂,可以揍我. 不论你是javascript新手还是老鸟,不论是面试求职,还是日常开发工作,我们经常会遇到这样的情况:给定 ...
- 彻底搞懂JavaScript执行机制
首先我们大家都了解的是,JavaScript 是一门单线程语言,所以我们就可以得出: JavaScript 是按照语句顺序执行的 首先看: let a = '1' console.log(a) let ...
- javascript等待异步线程完成_前端:什么是单线程,同步,异步?彻底弄懂 JavaScript 执行机制...
javascript是按照语句出现的顺序执行的. js是一行一行执行的: let a = '1';console.log(a);let b = '2';console.log(b); 然而实际上js是 ...
- animation 先执行一次 在持续执行_这一次,彻底弄懂 JavaScript 执行机制
本文来源:ssssyokihttps://juejin.im/post/6844903512845860872 不论你是javascript新手还是老鸟,不论是面试求职,还是日常开发工作,我们经常会遇 ...
- 一次性搞懂JavaScript 执行机制
你是否遭受到这样的恐吓? 你是否有过每个表达式前面都console一遍值去找执行顺序? 看了很多js执行机制的文章似乎都是似懂非懂,到技术面问的时候,理不清思绪.总结了众多文章的例子和精华,希望能帮到 ...
- 弄懂 JavaScript 执行机制,宏任务和微任务
本文的目的就是要保证你彻底弄懂javascript的执行机制. 不论你是javascript新手还是老鸟,不论是面试求职,还是日常开发工作,我们经常会遇到这样的情况:给定的几行代码,我们需要知道其输出 ...
最新文章
- Struts2 Cannot create a session after the response has been committed 一个不起眼的错误
- 图说子图同构算法——VF2算法(一)
- SAP RETAIL 我的第一个寄售类型的跨公司采购订单
- ubuntu9.10安装文泉驿微米黑字体
- OpenStack 虚拟机热迁移流程图
- SolrJ商品搜索实现
- ios UITableView顶部向下偏移
- Python使用Manager对象实现不同机器上的进程跨网络传输数据
- DRBD+Corosync+Pacemaker+MySQL(下)
- 就业管理系统(Java毕业设计:SpringBoot项目)
- ebay 后台HTML有尺寸宽度要求吗,Ebay后台有哪些常用的操作页面?
- 【实战】通过命令行调用360杀毒软件接口对指定文件或文件夹杀毒
- python3__机器学习__神经网络基础算法__偏执项b
- python 战舰_代码战争战舰受损或沉没Python
- MySQL数据库如何改名
- java后台证件号15转18位
- WebBowser 实现淘宝网自动登录
- IaaS PaaS SaaS 读音及含义
- Mac下配置VIM .vimrc
- 送给用 EditPlus 或 Programmer's Notepad 等编辑器写代码的朋友!
热门文章
- SQLserver锁和事务隔离级别的比较与使用
- Oracle 数据类型 选择自 tjandy 的 Blog
- .NET 框架中的字符串(转自MSDN,关于字符串的详细解说!)
- 使用内存硬盘(tmpfs)来加速你的网站
- 使用命令行 启动 各种服务(控制面板 开机启动项 注册表 等)
- Xshell不能链接虚拟机(可ping通)--解决方案
- Springboot中关于跨域问题的一种解决方法
- Windows无法安装到这个磁盘 选中的磁盘具有MBR分区表解决方法
- 如何在sh的字符串中包含换行符?
- 为什么git的“ pull request”不称为“ push request”?