我正在查看section 13或ECMAScript规范(v。5)。如下初始化匿名函数表达式:为什么匿名函数表达式和命名函数表达式初始化如此不同?
返回按照13.2中的规定,使用由FunctionBody指定的由FormalParameterListopt和Body指定的参数创建一个新的Function对象的结果。作为范围传递正在运行的执行上下文的LexicalEnvironment。如果FunctionExpression包含在严格代码中或者其FunctionBody是严格代码,则传入true作为Strict标志。
这个逻辑是很类似于如何初始化函数声明。但是,请注意命名函数表达式的不同初始化方式。
- 令funcEnv是调用NewDeclarativeEnvironment传递运行的执行上下文的词法环境作为 论证的结果
- 令envRec funcEnv的环境记录。
- 调用envRec的CreateImmutableBinding具体方法,传递Identifier的String值作为参数。
- 让闭包是根据13.2中的规定创建一个新的Function对象的结果,其参数由FormalParameterListopt 指定,并由FunctionBody指定。作为范围传递funcEnv。如果函数表达式包含在 严格代码中,或者其FunctionBody是严格代码,则将 作为严格标记。
- 调用envRec的InitializeImmutableBinding具体方法,传递Identifier和closure的String值作为参数。
- 退货关闭。
我知道的名为/匿名函数表达式之间的巨大差异之一就是有名函数表达式可以递归从函数中调用,但是这是所有我能想到的。为什么设置如此不同以及为什么需要执行这些额外的步骤?
还有其他的微妙之处。函数表达式名称绑定是只读的,但您仍然可以在函数表达式的主体中声明一个使用相同名称的var或函数。描述这种语义(记住这只是一个规范)需要使用额外的环境记录。 – 2013-03-01 20:05:02
有趣。但为什么这需要额外的环境记录?例如,如果NFE的标识符绑定是在第5步之前的函数声明(10.5)期间创建的,则源代码中的任何var/function声明只会覆盖NFE的绑定(5f)而不是将其隐藏。几乎相同的效果,不是吗? – kangax 2013-03-01 20:52:51