do expressions S1
中文标题:do 表达式
- 阶段: Stage 1
- 状态: 进行中
- ECMAScript 版本: —
- 同步时间: 2026年8月26日
- English original · 官方仓库
do 表达式提案通过允许块语句作为表达式使用,返回最后一条语句的完成值,将面向表达式的编程引入 ECMAScript。它旨在简化当前使用嵌套三元表达式或语句序列的代码,并且在如 JSX 的模板上下文中特别有用。
以下 README 来自上游仓库,其中的阶段或状态标注可能滞后;当前信息以提案概览为准。
ECMAScript 提案:do 表达式
本提案有 初步规范文本。
状态
本提案处于 TC39 流程 的 阶段 1。
动机
- 面向表达式的编程是函数式编程的重大进步之一
- 表达式像乐高积木一样拼接,使得小规模编程体验更加灵活
示例
以面向表达式的风格编写,尽可能局部地限定变量作用域:
将条件语句用作表达式,而不是笨拙的嵌套三元表达式:
特别适合像 JSX 这样的模板语言:
限制
由于可能造成混淆,你不能以声明、没有 else 的 if 或循环(即使嵌套在其他语句中)来结束 do 表达式。例如,以下都是早期错误:
更正式地说,StatementList 的完成值不能依赖于循环或声明的完成值。详见提议规范中的 EndsInIterationOrDeclaration。
对声明的限制尤其令人遗憾。这源于声明的完成值具有 ~empty~,意味着 do { 'before'; let x = 'after'; } 将求值为 before。我希望追求普遍改变声明的完成值,但这会影响依赖 eval 的现有代码。
边界情况
var 声明
允许 var 声明(除了作为最后一条语句),其绑定提升到包含函数的词法作用域。例外:当 do 出现在参数表达式中时,var 声明是早期错误。
空 do
允许 do {},它等同于 void 0。
await/yield
使用 await 和 yield 的能力继承自封闭函数的上下文,如同在任何其他表达式中一样。
throw
正常工作。做你期望的事情。
break/continue/return
在适当的上下文中允许使用:当 do 在函数内时允许 return,当在循环或 switch 分支内时允许 break 等等。这允许你编写如下代码:
异常情况
由于可能造成混淆,无论在循环内部是否有另一层循环,在循环头部都不允许使用未标记的 break 和 continue。
甚至在函数参数列表中允许 return,例如 function f(x = do { return null; }) {}。在类体的计算属性名中不允许。
与 do-while 的冲突
在语句合法的上下文中禁止使用 do 表达式。在这种上下文中,你可以使用普通块或将 do 表达式用括号括起来。
B.3.3 函数提升
宽松模式的函数提升不允许穿过 do 表达式。