什么是 Javascript 里的语句结束值(Statement Completion Value)?

本文译自 Matt Zeunert 的 Blog What’s a statement completion value in JavaScript?


Paul Irish 在 Twitter 上提了一个问题

相对于 "omg",你一定期望结果是 undefined,因为后者才是 var x = r 的执行结果

JavaScript 的创建者 Brendan Eich 回答了这个问题

为什么说它不是一个返回值,而是一个语句结束值statement completion value)呢?


什么是语句结束值

直觉上,一个语句结束值就是你执行了一段代码所得到的东西

比如说,在 console 里:

实际上,在 JavaScript 里获取语句结束值的唯一途径就是通过 eval 的调用所得到的值:

无论如何,语句结束值不仅仅是纯的 JavaScript 的值,JavaScript 引擎会在结束值外面包裹一个结束类型(completion type

除了普通的 JavaScript 值以外,结束类型还可以存储一个空(empty)值。例如,变量的声明就会以 empty 作为结束。但 empty 并不是 JavaScript 语言的一部分,所以 eval("var a") 返回了 undefined 而非 empty

为了理解我们开关提到的推文,我们需要看一下语句列是怎么处理这个特殊的 empty 类型的


语句列的表现

下面是语言标准里关于语句列的结束值的表述:

The value of a StatementList is the value of the last value producing item in the StatementList. For example, the following calls to the eval function all return the value 1:

eval(“1;;;;;”)
eval(“1;{}”)
eval(“1;var a;”)

eval("1;;;;;") 包含了一个表达式语句以及4个空语句。空语句会以 empty 结束。这意味着 1; 是这个语句列里唯一个产生非空值的语句。所以它就是最后一个产生值的项,整个语句列的就以 1 结束

上面的第二个例子,看起来像是应该返回一个空对象。但 {} 表示的是一个空的块语句,并且会以 empty 结束

最后一个例子和我们在文章开头看到的 twitter 很类似了

"omg"; var x = 4; 是一个包含两个语句的语句列。它们的结束值分别是 "omg"empty ,所以非空值 "omg" 会作为执行结果


ES2015 里的变化

ES2015 改变了一些语句的结束值。下面是一个对比了 Chrome 和 Firefox 的例子:

Firefox 遵守了 ES5 的规则:以 false 为条件的 if 语句的结束值会是 empty, 所以 "Hi" 就是最后一个非空值

但这种表现已经改变:在ES2015规则下,如果 if 语句的条件是 false ,那它会以 undefined 作为结束。正如截图所示, Chrome 已经实现了这个变化。

这里有一些 ES2015 下结束值变化的背景信息


本文译自 Matt Zeunert 的 Blog What’s a statement completion value in JavaScript?

原文作者: dgb8901,yinxing

原文链接: https://www.itwork.club/2020/01/07/statement-completion/

版权声明: 转载请注明出处

为您推荐

体验小程序「简易记账」

关注公众号「特想学英语」

在 Vue CLI 生成的项目里更改 eslint 风格