为什么记录命名的 IIFE 而不是同名变量?

Why is the named IIFE logged instead of the variable with the same name?

我看到下面有人发布的代码。我对它记录的内容感到困惑。它记录 函数 a,而不是 200。为什么?

var a = 1;
(function a() {
  a = 200;
  console.log(a)
})()

因为被立即调用的函数是命名的,并且该名称不能被重新分配以引用 IIFE 中的其他东西直接

任何命名函数表达式也会表现出这种行为。函数名为 a 的函数表达式意味着直接在函数内部的 a 将始终引用函数本身,即使您尝试重新分配它也是如此。

如果您使用严格模式,您可以将错误显式化:

'use strict';
var a = 1;
(function a() {
  a = 200;
  console.log(a)
})()

Uncaught TypeError: Assignment to constant variable.

拥有命名函数表达式有点像拥有

(function a() {
  const a = <this function>;
  // ...
})()

除了尝试重新分配它只会抛出严格模式。

具体来说,我相信此行为的 ECMAScript 5 规范在 SetMutableBinding:

  1. If the binding for N in envRec is a mutable binding, change its bound value to V.
  2. Else this must be an attempt to change the value of an immutable binding so if S (strict mode being used) if true throw a TypeError exception.

但直接在函数内部,函数名称绑定是不可变的 - 参见 Function Definition:

The production

FunctionExpression : function Identifier ( FormalParameterListopt ) { FunctionBody }

is evaluated as follows:

Call the CreateImmutableBinding concrete method of envRec, passing the String value of Identifier as the argument.