小tips:在JS语句执行机制涉及的一种基础类型Completion
看一个如下的例子。在函数 foo 中,使用了一组 try 语句。在 try 中有 return 语句,finally 中的内容还会执行吗?
function foo(){
try{
return 0;
} catch(err) {
} finally {
console.log("a")
}
}
得到的结果是:a 0。
根据结果可以看出finally执行了,return语句也生效了。
虽然 return 执行了,但是函数并没有立即返回,又执行了 finally 里面的内容,这样的行为违背了很多人的直觉。
我们改一下上面的例子,在finally也加入return语句,如下:
function foo(){
try{
return 0;
} catch(err) {
} finally {
return 1;
}
}
得到的结果是:1
通过实际执行,我们看到,finally 中的 return “覆盖”了 try 中的 return。在一个函数中执行了两次 return,这已经超出了很多人的常识,也是其它语言中不会出现的一种行为。
面对如此怪异的行为,我们当然可以把它作为一个孤立的知识去记忆,但是实际上,这背后有一套机制在运作。
这一机制的基础正是 JavaScript 语句执行的完成状态,我们用一个标准类型来表示:Completion Record(Completion Record 用于描述异常、跳出等语句执行过程)。
Completion Record 表示一个语句执行完之后的结果,它有三个字段:
- [[type]] 表示完成的类型,有 break continue return throw 和 normal 几种类型;
- [[value]] 表示语句的返回值,如果语句没有,则是 empty;
- [[target]] 表示语句的目标,通常是一个 JavaScript 标签。
JavaScript 正是依靠语句的 Completion Record 类型,方才可以在语句的复杂嵌套结构中,实现各种控制。接下来我们要来了解一下 JavaScript 使用 Completion Record 类型,控制语句执行的过程。
语句的分类如下:

普通语句执行后,会得到 [[type]] 为 normal 的 Completion Record,JavaScript 引擎遇到这样的 Completion Record,会继续执行下一条语句。
这些语句中,只有表达式语句会产生 [[value]],当然,从引擎控制的角度,这个 value 并没有什么用处。
如果你经常使用 chrome 自带的调试工具,可以知道,输入一个表达式,在控制台可以得到结果,但是在前面加上 var,就变成了 undefined。

Chrome 控制台显示的正是语句的 Completion Record 的 [[value]]。
现在解释下在finally也加入return语句后,为什么得到的结果为1?
因为 finally 中的内容必须保证执行,所以 try/catch 执行完毕,即使得到的结果是非 normal 型的完成记录,也必须要执行 finally。
而当 finally 执行也得到了非 normal 记录,则会使 finally 中的记录作为整个 try 结构的结果。
带标签的语句的作用:与完成记录类型中的 target 相配合,用于跳出多层循环。
实际上,任何 JavaScript 语句是可以加标签的,在语句前加冒号即可:
firstStatement: var i = 1;
跳出循环的例子:
top:
for (var i = 0; i < 3; i++){
for (var j = 0; j < 3; j++){
if (i === 1 && j === 1) break top;
console.log('i=' + i + ', j=' + j);
}
}
// i=0, j=0
// i=0, j=1
// i=0, j=2
// i=1, j=0
小tips:在JS语句执行机制涉及的一种基础类型Completion的更多相关文章
- JS 引擎执行机制
JS JS 是单线程语音 JS 的 Event Loop 是 JS 的执行机制.类似于 Android Handler 消息分发机制 JS 单线程 技术的出现都跟现实世界里的应用场景密切相关 JS 单 ...
- 浅析JS异步执行机制
前言 JS异步执行机制具有非常重要的地位,尤其体现在回调函数和事件等方面.本文将针对JS异步执行机制进行一个简单的分析. 从一份代码讲起 下面是两个经典的JS定时执行函数,这两个函数的区别相信对JS有 ...
- 小tips:JS之浅拷贝与深拷贝
浅拷贝: function extendCopy(p) { var c = {}; for (var i in p) { c[i] = p[i]; } return c; } 深拷贝: functio ...
- 深入理解 JS 引擎执行机制(同步执行、异步执行以及同步中的异步执行)
首先明确两点: 1.JS 执行机制是单线程. 2.JS的Event loop是JS的执行机制,深入了解Event loop,就等于深入了解JS引擎的执行. 单线程执行带来什么问题? 在JS执行中都是单 ...
- JS代码执行机制
JS代码从编译到执行 我们写出一段JS代码,JS的引擎并不是按照我们书写的顺序从上到下顺序编译并且执行的,首先是按照自己的规则对我们的代码先进行编译,然后从上到下执行编译的代码. 在全局作用域中,JS ...
- js的执行机制
遇到一个问题,因为自己本身就是菜鸟的原因,弄懂了还是很高兴的. console.log(a) function a() { return "this is function" } ...
- 小tips:JS数值之间的转换,JS中最大的Number是多少?,JS == 与 === 的区别
JS数值之间的转换 Number(), parseInt(),parseFloat() Number()函数的转换规则如下: 1.如果boolean值,true和false将分别被转换为1和02.如果 ...
- 小tips:JS之break,continue和return这三个语句的用法
break语句 break语句会使运行的程序立刻退出包含在最内层的循环或者退出一个switch语句.由于它是用来退出循环或者switch语句,所以只有当它出现在这些语句时,这种形式的break语句才是 ...
- 小tips:JS中typeof与instanceof用法
介绍 typeof typeof用以获取一个变量或者表达式的类型,typeof一般只能返回如下几个结果: number boolean string function(函数) object(NULL, ...
随机推荐
- N种自动化测试框架(包含自动化和性能,总有一款适合你)
不知不觉,分享的框架已经6个了(准确说应该是4个),仅仅是接口的. 这些框架都是最基础的框架,需要根据实际使用场景进行完善,大家就当练手实践吧. 不需要写代码的自动化框架 JMeter + Ant+ ...
- ActiveMQ 入门和与 Spring 整合
ActiveMQ 入门演示 activemq 依赖 <dependency> <groupId>org.apache.activemq</groupId> < ...
- python3中“->”的含义
->:标记返回函数注释,信息作为.__annotations__属性提供 __annotations__属性是字典.键return是用于在箭头后检索值的键.但是在Python中3.5,PEP 4 ...
- Layui 关闭当前标签页
parent.layui.admin.events.closeThisTabs();
- STL——list用法总结
头文件 #include<list> 声明一个int型的list:list<int> a: 1.list的构造函数 list<int>a{1,2,3} list&l ...
- c++primer(第五版) 阅读笔记_第1章
一.结构图: 二.代码及练习题 1.1节 编写一个简单的C++程序 1.1节练习 练习1.1: 查阅使用的编译器的文档:我使用的是vs2013,其文档为https://docs.microsoft.c ...
- 1-7docke的网络模式
1.Bridge模式 bridge 模式是 docker 的默认⽹络模式,不写 –net 参数,就是 bridge 模式.比如使⽤ docker run - p 时 工作模式从网上找了一个,如下 例子 ...
- [.Net,C#]三类资源:流对象Stream,字节数组byte[],图片Image
三类资源:流对象Stream,字节数组byte[],图片Image 关系:Stream<=>byte[],byte[]<=>Image Stream 与Image相互转化的媒介 ...
- window 运行spark报错
Using Spark's default log4j profile: org/apache/spark/log4j-defaults.properties // :: ERROR Shell: F ...
- spring JDBC的应用
原文地址:https://www.iteye.com/blog/chen106106-1574911 1:首先在类路径下面配置访问数据的一些基本信息,包括连接数据库的地址,用户,密码jdbc.prop ...