IIFE内可变吊装(延迟解析)

ank*_*aha 6 javascript hoisting

我在下面的场景中得到了一个非常奇怪的输出:

function test(){
   var test=123;
   console.log(test)
}
// this output : 123

(function test(){
   var test=123;
   console.log(test)
})()

// this output: 123 
Run Code Online (Sandbox Code Playgroud)

但是在使用下面的代码时

(function test(){
   test=123;
   console.log(test)
})()

//output:

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

任何人都可以解释一下.

T.J*_*der 9

你所看到的与吊装无关.

你的第一个例子很简单:

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

您正在创建一个在函数范围内var调用的变量(via )test,并为其赋值,然后输出该值.

你的第二个例子遗漏了var:

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

...... test具有完全不同的含义:在由命名函数表达式创建的函数中,函数的名称是解析函数的标识符.因此test,代码是函数的标识符.

当您使用函数表达式时,该标识符是只读的,因此test = 123;忽略您的行,并且该console.log行输出函数的表示(好像test = 123;根本不存在).

我忘记了标识符是只读的(当由表达式创建时),但它是:从规范:

FunctionExpression:functionBindingIdentifier(FormalParameters){FunctionBody}

  1. 如果FunctionExpression的函数代码是严格模式代码,则let strict为true.否则严格要假.
  2. scope成为正在运行的执行上下文的LexicalEnvironment.
  3. funcEnv成为NewDeclarativeEnvironment(范围).
  4. envRec成为funcEnv的EnvironmentRecord.
  5. nameBindingIdentifier的 StringValue .
  6. 执行envRec.CreateImmutableBinding(name,false).
  7. ...

注意步骤6:创建标识符的绑定是不可变的(不能更改).

请注意,对于由函数声明创建的标识符(绑定),情况并非如此,这是可变的; 但函数表达式和函数声明完全不同地处理函数名称创建的标识符.(例如:函数声明将名称放在声明所在的作用域中,但函数表达式不会.)

  • @ankurkushwaha:在没有IIFE的片段中你也使用`var` (2认同)