根据ECMA-262规范,FunctionDeclarationInstantiation抽象操作的作用是什么?
函数声明实例化(FunctionDeclarationInstantiation)功能详解
这个抽象操作是ECMAScript引擎执行函数的前置核心逻辑,运行时机在函数执行上下文创建完成后,函数体内任意可执行代码运行前,核心作用是完成当前函数作用域内所有标识符的绑定初始化,搭建函数的作用域运行基础。
核心执行流程
- 形参绑定初始化
首先完成形参与实参的映射绑定:按照调用时传入的实参给对应位置的形参赋值,未传参的形参默认赋值为undefined;如果形参配置了默认值,会在这个阶段执行默认值表达式完成赋值;如果形参包含解构、剩余参数语法,也会在这一步完成对应的解构赋值操作。 - 函数声明提升处理
遍历函数体所有顶层的函数声明,为每个函数名在当前作用域创建绑定,同时直接完成函数对象的初始化赋值。如果遇到同名的形参或已创建的变量绑定,函数声明的绑定会直接覆盖原有值,这也是“函数提升优先级高于变量提升”规则的底层来源。 - 变量声明提升处理
遍历函数体所有顶层的var变量声明,为每个变量名在当前作用域创建绑定,仅当该标识符还没有被绑定过的时候,才会将其初始化为undefined;如果已经存在同名的形参、函数声明绑定,这一步不会修改已有的绑定值。 - 特殊标识符绑定(非箭头函数场景)
如果当前函数不是箭头函数,会在这一步完成两个额外绑定:- 创建
arguments对象并绑定到当前作用域,非严格模式下arguments会和形参保持联动修改,严格模式下二者相互独立 - 按照函数的调用方式完成
this指向的绑定,箭头函数的this继承自外层作用域,所以不会在这个阶段处理。
- 创建
行为示例
我们可以通过一个典型的提升场景直观看到这个操作的作用:
function test(a) { console.log(a); console.log(b); function a() { return "function a"; } var b = "var b"; console.log(a); console.log(b); } test(10);
运行输出结果为:
[Function: a]
undefined
[Function: a]
var b
对应逻辑完全匹配函数声明实例化的执行规则:
- 形参绑定阶段,
a被赋值为传入的实参10 - 函数声明处理阶段,发现同名函数
a,直接覆盖a的绑定,将其赋值为函数对象 - 变量声明处理阶段,发现
var b无现有绑定,初始化为undefined - 进入执行阶段后前两行打印的就是实例化阶段完成的绑定值,后续手动赋值后才会更新对应标识符的值。
内容的提问来源于stack exchange,提问作者AngryJohn
相关产品推荐
相关产品推荐

