Variable hoisting inside IIFE (lazy parsing)

馋奶兔 提交于 2019-11-30 05:18:49

问题


I am getting a very strange output on the below scenarios:

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

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

// this output: 123 

But when using the below code

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

//output:

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

Can anybody please explain.


回答1:


What you're seeing isn't related to hoisting.

Your first example is quite straightforward:

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

You're creating a variable (via var) called test within the scope of the function, and assigning it a value, then outputting that value.

Your second example leaves out var:

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

...and so test has quite a different meaning: Within a function created by a named function expression, the function's name is an identifier resolving to the function. So test in that code is an identifier for the function.

That identifier is read-only when you've used a function expression, so your test = 123; line is ignored, and the console.log line outputs a representation of the function (as though test = 123; weren't there at all).

I'd forgotten that identifier is read-only (when created by an expression), but it is: From the specification:

FunctionExpression : functionBindingIdentifier ( FormalParameters ) {FunctionBody}

  1. If the function code for FunctionExpression is strict mode code, let strict be true. Otherwise let strict be false.
  2. Let scope be the running execution context's LexicalEnvironment.
  3. Let funcEnv be NewDeclarativeEnvironment(scope).
  4. Let envRec be funcEnv's EnvironmentRecord.
  5. Let name be StringValue of BindingIdentifier.
  6. Perform envRec.CreateImmutableBinding(name, false).
  7. ...

Note Step 6: The binding creating the identifier is immutable (can't be changed).

Note that this isn't true for the identifier (binding) created by a function declaration, which is mutable; but function expressions and function declarations treat the identifiers created by the function name completely differently. (For instance: A function declaration puts the name in scope where the declaration is, but a function expression doesn't.)



来源:https://stackoverflow.com/questions/42738909/variable-hoisting-inside-iife-lazy-parsing

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!