Is a function hoisted if it is defined within an if condition?

做~自己de王妃 提交于 2019-12-22 05:06:22

问题


So suppose I have something like this

var x = 1;
   if (function f(){}) {
     x += typeof f;
   }
   x;

This outputs "1undefined". I thought it should have output "1function", because function f(){} should have been hoisted above the if. This is clearly not the case - why? I thought function declarations and bodies were always hoisted to the top of the scope?


回答1:


Function declarations are hoisted. Function expressions are not.

This creates a named function expression:

if(function f(){})

It doesn't do anything except check to see if the function expression is truthy. (Function expressions are always truthy.)

Regarding named function expressions, see https://kangax.github.io/nfe/#named-expr:

An important detail to remember is that this name is only available in the scope of a newly-defined function

This code is outside the scope of the new function expression, and therefore f is undefined:

x += typeof f;

Within a named function expression, you can refer to its name without a problem:

(function f() {
  alert(typeof f);   //function
})();

alert(typeof f);     //undefined



回答2:


As far as I know ES5 does not define the behavior for function declarations inside blocks.

Quoting Kangax:

FunctionDeclarations are only allowed to appear in Program or FunctionBody. Syntactically, they can not appear in Block ({ ... }) — such as that of if, while or for statements. This is because Blocks can only contain Statements, not SourceElements, which FunctionDeclaration is. If we look at production rules carefully, we can see that the only way Expression is allowed directly within Block is when it is part of ExpressionStatement. However, ExpressionStatement is explicitly defined to not begin with "function" keyword, and this is exactly why FunctionDeclaration cannot appear directly within a Statement or Block (note that Block is merely a list of Statements).

Because of these restrictions, whenever function appears directly in a block (such as in the previous example) it should actually be considered a syntax error, not function declaration or expression. The problem is that almost none of the implementations I've seen parse these functions strictly per rules (exceptions are BESEN and DMDScript). They interpret them in proprietary ways instead.




回答3:


Function declarations are statements. The conditional part of an if-statement is an expression, so what you have is a function expression; it cannot be a function declaration. And so it isn't hoisted, since only function declarations are.



来源:https://stackoverflow.com/questions/31664040/is-a-function-hoisted-if-it-is-defined-within-an-if-condition

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