You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ECMAScript技术疑问:VarScopedDeclarations是否返回FunctionDeclaration?

ECMAScript规范相关疑问解答

背景

我正在研读ECMAScript规范,试图理解简单脚本从启动到执行完毕的完整求值流程。结合此前的问答内容,我梳理了**GlobalDeclarationInstantiation(全局声明实例化)**的流程,目标是搞清楚FunctionDeclaration(函数声明)如何被实例化(将标识符添加至全局环境记录GER)并完成初始化(为GER中的标识符赋值)。

过程中我注意到GlobalDeclarationInstantiation的第5步:

Let varDeclarations be the VarScopedDeclarations of script.

查看**VarScopedDeclarations(变量作用域声明)**的定义后,我发现它似乎从不返回FunctionDeclaration的解析节点。实际上,除了VarDeclarations(变量声明)外,它对所有语法符号都返回空列表,也就是说它仅返回带var关键字的声明对应的解析节点。例如var a = 5的VarScopedDeclarations会返回包含a = 5的解析节点。

疑问

  • VarScopedDeclarations是否会返回FunctionDeclaration的解析节点?
  • 如果不会,那么GlobalDeclarationInstantiation第8.1.i步中的断言(i. Assert: d is either a FunctionDeclaration...)是否有可能成立?
  • 既然VarScopedDeclarations对多数符号都返回空列表,规范制定者为何还要将它们纳入?仅保留实际会返回解析节点的符号是否更简洁?LexicallyScopedDeclarations(词法作用域声明)及其他部分操作也存在同样情况。

解答

1. VarScopedDeclarations不会返回FunctionDeclaration的解析节点

根据ECMAScript规范的静态语义定义,VarScopedDeclarations仅收集var相关声明(包括变量声明、for绑定等)对应的解析节点。FunctionDeclaration属于词法作用域声明的范畴,不会被VarScopedDeclarations收集。

2. 断言可以成立,因为它处理的是合并后的声明列表

你提到的第8.1.i步断言,针对的是合并后的声明集合,而非单独的varDeclarations。在GlobalDeclarationInstantiation流程中,规范会先将functionDeclarations(从LexicallyScopedDeclarations中筛选出的函数声明)与varDeclarations合并为一个新列表declarations,后续遍历处理的正是这个合并后的列表。当遍历到来自functionDeclarations的元素时,断言d is either a FunctionDeclaration...自然成立。

3. 保留全量语法符号是为了规范的严谨性与一致性

规范为所有语法符号定义VarScopedDeclarations(以及LexicallyScopedDeclarations)的返回值,核心原因是保证静态语义规则的完整性与通用性:

  • 语法本身是递归定义的,静态语义规则需要覆盖所有可能的语法节点,避免出现未定义的边界情况;
  • 统一的规则结构让规范更易维护,新增语法特性时只需扩展对应规则,无需修改整体框架;
  • 即使部分符号返回空列表,也明确了它们不属于变量作用域声明的范畴,消除歧义。这种设计是规范编写的通用模式,确保语义定义严谨、无遗漏。

内容的提问来源于stack exchange,提问作者Magnus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 17:25:25