如果在if条件中定义了函数,是否会被提升?

时间:2015-07-27 21:57:53

标签: javascript hoisting

假设我有类似的东西

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

输出“1undefined”。我认为它应该输出“1function”,因为函数f(){}应该在if之上被提升。事实显然不是这样 - 为什么?我认为函数声明和主体总是被提升到范围的顶部?

3 个答案:

答案 0 :(得分:6)

函数声明已悬挂。函数表达式are not

这将创建一个名为的函数表达式:

if(function f(){})

除了检查函数表达式是否真实之外,它什么都不做。 (函数表达式总是很简洁。)

关于命名函数表达式,请参阅https://kangax.github.io/nfe/#named-expr

  

要记住的一个重要细节是,此名称仅适用于   新定义函数的范围

此代码之外新函数表达式的范围,因此f未定义:

x += typeof f;

命名函数表达式中,您可以毫无问题地引用其名称:

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

alert(typeof f);     //undefined

答案 1 :(得分:4)

据我所知,ES5没有定义块内函数声明的行为。

引用Kangax

  

FunctionDeclarations只允许出现在Program或   函数体。在句法上,它们不能出现在Block ({...})中 -   例如if,while或for语句。这是因为块   只能包含语句,而不是SourceElements   FunctionDeclaration是。如果我们仔细研究生产规则,我们   可以看到Expression直接允许在Block中使用的唯一方法   是什么时候它是ExpressionStatement的一部分。然而,   ExpressionStatement被明确定义为不以" function"开头。   关键字,这正是FunctionDeclaration无法出现的原因   直接在Statement或Block中(注意Block只是一个列表   声明)。

     

由于这些限制,只要函数直接出现在a中   它应该实际上是块(例如在前面的例子中)   考虑语法错误,而不是函数声明或表达式。该   问题是我所见过的几乎所有实现都没有解析   严格按照规则执行这些功能(例外情况是BESEN和   DMDScript)。他们用专有的方式解释它们。

答案 2 :(得分:0)

函数声明为statementsif-statement的条件部分是一个表达式,所以你拥有的是一个函数表达式;它不能是一个函数声明。所以它不会被提升,因为只有函数声明