为什么在 JavaScript 中将函数声明作为 If 语句的主体不会导致错误?

问题描述 投票:0回答:3

在“声明和声明”的 MDN 文档中提到:

术语“语句”和“声明”在 JavaScript 的正式语法中具有精确的含义,会影响它们在代码中的放置位置。例如,在大多数控制流结构中,主体仅接受语句,例如 if...else 的两个分支。如果使用声明而不是语句,则会出现语法错误。例如,let 声明不是语句,因此您不能将其以其裸露形式用作 if 语句的主体。

下面的代码会报错:

if(true) 
  let x = 0;

现在函数声明也只是声明吧?那么为什么下面的代码没有给出同样的错误呢?

if(true)
function foo() {}
javascript if-statement conditional-statements syntax-error language-lawyer
3个回答
2
投票

5.1 版注释专门解决了这个问题:

已知多种广泛使用的 ECMAScript 实现支持使用 FunctionDeclaration 作为 Statement。然而,应用于此类FunctionDeclarations的语义实现之间存在显着且不可调和的差异。由于这些不可调和的差异,使用 FunctionDeclaration 作为 Statement 会导致代码在实现之间无法可靠地移植。建议 ECMAScript 实现禁止使用 FunctionDeclaration 或在遇到此类用法时发出警告。 ECMAScript 的未来版本可能会定义替代的可移植方法,用于在 Statement 上下文中声明函数。

下一版当前版本,第一个构造由附件 B 中指定的附加功能覆盖,当主机是 Web 浏览器时,这是必需的:

IfStatement[屈服、等待、返回]:

   

if
(
表达式[+In, ?Yield, ?Await]
)
函数声明[?Yield, ?Await, ~默认]


-3
投票
if (true) {
  const foo = function() {};
}

在这种情况下,foo 函数将仅在 if 语句的块内定义,遵守块作用域规则。


-3
投票

因为使用 function 关键字声明函数会将其置于全局范围内。

做个简单的测试:

if (true) {
   function foo(x) { return x+2 }
}
console.log(foo(5))

将在控制台中产生“7”,证明该函数实际上是在 if 之外定义的。

相反,在 if 内显式定义的变量将被限定在 if 范围内。

注意此代码会引发错误,因为 bar 不会在 if 之外定义。

if (true) {
    const bar = function (x) { return x+2 }
}
console.log(bar(5))
© www.soinside.com 2019 - 2024. All rights reserved.