JavaScript中Allman风格的危险含义



我不记得在哪里了,但最近我发表了一条评论,用户告诉 1TBS 在 JavaScript 中比 Allman 更受欢迎,并说 Allman 在 JavaScript 中具有危险的含义。

这是一个有效的说法吗?如果是这样,为什么?

return不能在它之后LineTerminator,因此:

return
{

};

被视为return;(返回undefined)而不是return {};(返回对象)

请参阅Automatic Semicolon Insertion (ASI)规则了解更多信息。

这是一个有效的语句。

因为JavaScript的引擎有所谓的ASI(自动分号插入),如果需要,它会在行返回时插入分号。"如有必要"是模棱两可的;有时有效,有时无效。请参阅规则。

因此,正如其他答案中所述:

return
{
};
// Is read by the JavaScript engine, after ASI, as:
return; // returns undefined
{ // so this is not even executed
};

因此,不建议将其用于return语句。

但是,如果您的指南建议函数声明使用 Allman 样式,则完全没问题。我知道有些人这样做。

我认为这取决于陈述。 例如,如果左大括号位于新行上,则 return 语句可能会中断。 更多信息在这里。

return {
    a: "A",
    b: "B"
};
// vs.
return // Semicolon automatically inserted here! Uh oh!
{
    a: "A",
    b: "B"
}

只要您记住一个带有关键字 returnthrow 的特殊情况,您就可以使用 Allman 或 Allman-8 样式。

将对象文字与通过换行符returnthrow的关键字分开在 JavaScript 中不起作用,因为 ASI 规则对 throwreturn 语句有一个特殊的例外:

  1. 当程序从左到右解析时,遇到语法的某些生产所允许的标记,但是生产是受限制的生产,代币将是第一个紧跟在限制生产中的注释"[此处没有线路终结者]"(因此这样的令牌称为受限令牌),并且受限令牌与上一个令牌之间至少隔一个行终止符,然后在受限令牌。

注意 以下是语法:
[...]返回声明
return [此处没有行终结符]表达式 ;
投掷声明
throw [此处没有行终止符]表达式 ;

(还有其他受限制的作品,但那些不支持大括号,所以它们对奥尔曼风格并不重要。

实际上,这并不像您期望的那样工作

return
{
        status: "successful",
        user:
        {
               id: "9abf38a3-c2f5-4159-a1be-0eccbc1b2349",
               label: "John Doe",
        },
};

因为它将被解释为(注意返回后的分号!

return;
{
        status: "successful",
        user:
        {
               id: "9abf38a3-c2f5-4159-a1be-0eccbc1b2349",
               label: "John Doe",
        },
};

因此,您必须使用语法

const response =
{
        status: "successful",
        user:
        {
               id: "9abf38a3-c2f5-4159-a1be-0eccbc1b2349",
               label: "John Doe",
        },
};
return response;

return {
        status: "successful",
        user:
        {
               id: "9abf38a3-c2f5-4159-a1be-0eccbc1b2349",
               label: "John Doe",
        },
};

相反。

我个人认为在任何情况下命名返回的结构都更具可读性,所以我使用它。我还在任何地方使用 Allman-8,这实际上意味着您使用 8 个空格宽度的制表符并使用单个制表符而不是 1 个或多个空格缩进所有内容。

理论上,有人也可以写

throw
{
        status: "error",
        code: 12,
        details: localvar,
};

这也将失败,因为由于上面的 ASI 规则,关键字 throw 之后会立即插入分号。在现实世界中,每个人似乎都写throw new ...throw localvar

我不知道这些异常的历史,但我只能假设这是一些历史事故,由于现有的现实世界代码依赖于这种事故,因此无法再修复。我没有看到任何这种自动分号实际上有益的结构,所以我认为这只是历史规范中的一个错误。(returnthrow后面的代码不能合理地以对象文字开头,因此它无论如何都不适用于插入的分号。

最新更新