ECMAScript中FunctionDeclaration无绑定为何可调用?我遗漏了什么?
问题解答
你混淆了函数声明的两个核心处理阶段:词法环境初始化(函数提升) 和 运行时求值,这是关键遗漏点:
- 函数声明的标识符绑定逻辑,根本不在
Runtime Semantics: Evaluation步骤中完成,而是在代码执行前的执行上下文初始化阶段就处理完毕:
当进入全局或函数执行上下文时,JS引擎会先扫描所有函数声明,创建对应的函数对象,并在当前的Declarative Environment Record(DER)中完成标识符与函数对象的绑定——这就是常说的函数提升。 Runtime Semantics: Evaluation阶段对FunctionDeclaration返回empty,只是表示这个语法节点在运行时不需要额外执行逻辑,因为绑定工作已经提前完成了。- 而函数表达式的绑定才是在求值阶段完成的,所以它不会被提升,必须等到代码执行到对应行才能访问。
举个直观对比示例:
// 正常执行,函数声明已提前完成绑定 console.log(foo()); function foo() { return 'bar'; } // 触发ReferenceError,函数表达式未完成绑定 console.log(baz()); const baz = function() { return 'qux'; }
简单来说:你只关注了函数声明的运行时求值阶段,却忽略了它在执行上下文初始化阶段就已经完成的绑定操作,这就是实际调用foo()不会报错的原因。
内容的提问来源于stack exchange,提问作者Magnus
相关产品推荐
相关产品推荐

