我得到了意想不到的结果.这是代码:
b = function c() {
console.log(c);
c = 3;
console.log(c);
}
b();Run Code Online (Sandbox Code Playgroud)
我认为第二个console.log应该打印"3",但我得到了函数本身.为什么?
同时,从下面的代码我得到了正确的"3".
function ff() {
ff = 3;
console.log(ff);
}
ff();Run Code Online (Sandbox Code Playgroud)
我正在查看第13节或ECMAScript规范(第5节).匿名函数表达式初始化如下:
返回使用FormalParameterListopt指定的参数和FunctionBody指定的主体创建13.2中指定的新Function对象的结果.将正在运行的执行上下文的LexicalEnvironment作为Scope传递.如果FunctionExpression包含在严格代码中或者其FunctionBody是严格代码,则传入true作为Strict标志.
这个逻辑与初始化函数声明的方式非常相似.但是,请注意命名的funciton表达式的不同初始化方式.
- 让funcEnv成为调用NewDeclarativeEnvironment传递正在运行的执行上下文的Lexical Environment作为参数的结果
- 让envRec成为funcEnv的环境记录.
- 调用envRec的CreateImmutableBinding具体方法,将Identifier的String值作为参数传递.
- 让闭包是创建一个新的Function对象的结果,该对象在13.2中指定,其中参数由FormalParameterListopt和FunctionBody指定的body指定.传入funcEnv作为范围.如果FunctionExpression包含在严格代码中或者其FunctionBody是严格代码,则传入true作为Strict标志.
- 调用envRec的InitializeImmutableBinding具体方法,将Identifier和closure的String值作为参数传递.
- 关闭.
我知道命名/匿名函数表达式之间的一个重大区别是命名函数表达式可以在函数内递归调用,但这就是我能想到的.为什么设置如此不同?为什么需要执行这些额外的步骤?