【问题标题】:Why is the named IIFE logged instead of the variable with the same name?为什么记录命名的 IIFE 而不是同名的变量?
【发布时间】:2019-11-14 20:41:22
【问题描述】:

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

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

【问题讨论】:

  • 如果有人想知道什么是 IIFE?然后是它的立即调用函数表达式或自执行匿名函数

标签: javascript iife


【解决方案1】:

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

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

如果你使用严格模式,你可以明确错误:

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

未捕获的类型错误:赋值给常量变量。

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

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

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

具体来说,我相信针对这种行为的 ECMAScript 5 规范在 SetMutableBinding

  1. 如果 envRec 中 N 的绑定是可变绑定,请将其绑定值更改为 V。
  2. 否则,这必须是尝试更改不可变绑定的值,因此如果 S(使用严格模式)如果为 true,则会引发 TypeError 异常。

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

制作

FunctionExpression : function Identifier ( FormalParameterListopt ) { FunctionBody }

评估如下:

调用envRec的CreateImmutableBinding具体方法,传入Identifier的String值作为参数。

【讨论】:

  • 您能否指出有关此行为的一些规范。一方面,我怀疑它不需要“立即调用”,setTimeout((function a() { a = 200; console.log(a) }), 1000) 会采取同样的行动。
  • 知道了,it's here 并且怀疑它适用于所有命名的 FunctionExpressions,而不仅仅是 ImmediatelyInvoked 的(我不认为是语言中的一个东西,只是一个用法)
猜你喜欢
  • 2021-11-28
  • 2021-07-15
  • 1970-01-01
  • 1970-01-01
  • 2011-07-10
  • 2015-12-17
  • 2014-10-10
  • 1970-01-01
相关资源
最近更新 更多