函数体和函数本身的变量具有相同的名称(JavaScript)

Rom*_*aev 8 javascript scope function function-declaration function-expression

(function test() {
  test = 123;
  console.log( test );
}());
Run Code Online (Sandbox Code Playgroud)

此功能在控制台中打印它的主体,但不是'123'.这种行为的原因是什么?

我对函数执行的解释失败了?

  1. 开始执行功能; 'test'是一个引用函数本身的局部变量;
  2. 局部变量'test'被重新分配到123号;
  3. console.log变量'test',这是一个数字.

Jam*_*gne 5

我相信这段ecma规范解释了这种行为.这特别涉及命名的 函数表达式

生产

FunctionExpression:function Identifier(FormalParameterListopt){FunctionBody}

评估如下:

  1. 让funcEnv成为调用NewDeclarativeEnvironment传递正在运行的执行上下文的Lexical Environment作为参数的结果
  2. 让envRec成为funcEnv的环境记录.
  3. 调用envRec的CreateImmutableBinding具体方法,将Identifier的String值作为参数传递.
  4. 让闭包是创建一个新的Function对象的结果,该对象在13.2中指定,其中参数由FormalParameterListopt和FunctionBody指定的body指定.传入funcEnv作为范围.如果FunctionExpression包含在严格代码中或者其FunctionBody是严格代码,则传入true作为Strict标志.
  5. 调用envRec的InitializeImmutableBinding具体方法,将Identifier和closure的String值作为参数传递.
  6. 关闭.

使用CreateImmutableBinding创建一个名为函数表达式的范围时,产生所述标识符(在这种情况下test),为不可变的变量.这就是为什么赋值不会改变它的价值.

  • @RomanBelyaev一旦你将`var`添加到`test`中,你就创建了一个本地`test`,而不是试图重新分配不可变的 (4认同)
  • 相关的是为什么这样做的讨论http://stackoverflow.com/questions/15129504/why-are-anonymous-function-expressions-and-named-function-expressions-initialize (2认同)