Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 在if条件下定义的功能是否被提升?_Javascript_Hoisting - Fatal编程技术网

Javascript 在if条件下定义的功能是否被提升?

Javascript 在if条件下定义的功能是否被提升?,javascript,hoisting,Javascript,Hoisting,假设我有这样的东西 var x = 1; if (function f(){}) { x += typeof f; } x; 这将输出“1未定义”。我认为它应该输出“1function”,因为函数f(){}应该被提升到if之上。这显然不是事实——为什么?我以为函数声明和主体总是被提升到范围的顶部 据我所知,ES5没有定义块内函数声明的行为 引述: 函数声明只允许出现在程序或 功能体。在语法上,它们不能出现在块中({…})- 例如if、while或for语句。这是因为

假设我有这样的东西

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

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

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

引述:

函数声明只允许出现在程序或 功能体。在语法上,它们不能出现在块中({…})- 例如if、while或for语句。这是因为积木 只能包含语句,不能包含SourceElements,因为 功能声明是。如果我们仔细研究生产规则,我们会 可以看出,在块中直接允许表达式的唯一方式 是当它是表达陈述的一部分时。然而, ExpressionStatement被明确定义为不以“function”开头 关键字,这正是FunctionDeclaration无法出现的原因 直接在语句或块中(请注意,块只是一个列表 (包括声明)

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


功能声明已悬挂。函数表达式

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

if(function f(){})
除了检查函数表达式是否真实之外,它什么都不做。(函数表达式总是真实的。)

关于命名函数表达式,请参见:

需要记住的一个重要细节是,此名称仅在中可用 新定义功能的范围

此代码不在新函数表达式的范围内,因此未定义
f

x += typeof f;
在命名函数表达式中,可以毫无问题地引用其名称:

(函数f(){
警报(typeof f);//函数
})();

警报(f型)//未定义的
函数声明不可用。一个函数的条件部分是一个表达式,所以你得到的是一个函数表达式;它不能是函数声明。所以它没有被提升,因为只有函数声明被提升。

实际上,它是,请看:我认为这是一个命名函数表达式,而不是函数声明。名称的作用域只是所定义函数的主体,而不是周围的函数。
Block
真的指的是
if()
部分还是它后面的
{body}
部分吗?我几乎可以肯定
if()
本身也被认为是块。。。但不是100%:(因为你可以在
for()
中声明一个变量,并且它只在它的块中有效…我想如果你在引号之前查看代码,它的工作方式是一样的,看起来我是在写。他说的是
if(foo){function bar(){…}
是的,OP代码中的函数不在a中,a被定义为
{StatementList}
。我不认为
与字符串
相关。函数是对象类型,也是对象类型。这里要理解的一个关键点是
函数f(){}
本身就是一个函数声明(如果被提升的话)。但是,由于分组运算符(括号)只能包含一个表达式,因此用括号包围它会使它成为一个函数表达式(未被提升)。