3

我有这些功能:

function A1()
{
    return B() && C();
}

function A2()
{
    return
        B() && 
        C();
}

function B()
{
    return true;
}

function C()
{
    return true;
}

调用 A1 返回 true,但 A2 返回 undefined。A1 和 A2 之间的唯一区别是空白。到底是怎么回事?在我的真实代码中,我不想将我的 A1 函数 a 写成一行,因为它会很长而且可读性差。

4

2 回答 2

7

您正在成为自动分号插入的受害者。解释器将在您的 return 语句后添加一个分号,因此这实际上是正在发生的事情:

function A2()
{
    return;
    //    ^ Automatically inserted semicolon
        B() && 
        C();
}

由于您现在有一个return没有显式返回值的语句,因此该函数将返回undefined

如果您查看return规范中语句的语法:

ReturnStatement :
  return [此处没有LineTerminator ]表达式;

您可以看到它不允许在return关键字和表达式之间使用行终止符(这被称为“限制生产”)。如果遇到行终止符,则应用自动分号插入的第三条规则:

当程序从左到右解析时,遇到语法的某些产生式允许的令牌,但产生式是受限产生式,并且该令牌将是紧接在注释之后的终端或非终端的第一个令牌“[no LineTerminator here]”在受限产生式中(因此这样的记号被称为受限记号),并且受限记号与前一个记号至少有一个 LineTerminator 隔开,然后在受限记号前自动插入分号.


我不想将我的 A1 函数 a 写成一行,因为它会很长......

您仍然可以return在多行中中断语句,您只需要注意放置换行符的位置(只需确保它们出现在表达式中而不是在它之前):

function A2()
{
    return B() &&
    //           ^ Invalid to put a semicolon here, so ASI doesn't apply
        C();
}
于 2013-07-02T09:47:38.500 回答
1
return (
    B() && 
    C()
);

也会起作用

于 2013-07-02T10:00:43.880 回答