假设我有类似的东西
var x = 1;
if (function f(){}) {
x += typeof f;
}
x;
输出“1undefined”。我认为它应该输出“1function”,因为函数f(){}应该在if之上被提升。事实显然不是这样 - 为什么?我认为函数声明和主体总是被提升到范围的顶部?
答案 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)
函数声明为statements。 if-statement的条件部分是一个表达式,所以你拥有的是一个函数表达式;它不能是一个函数声明。所以它不会被提升,因为只有函数声明。