12

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

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

4

5 回答 5

21

return不能有LineTerminator这样的:

return
{


};

被视为return;(return undefined) 而不是return {};(return an object)

有关更多信息,请参阅规则Automatic Semicolon Insertion (ASI)

于 2012-06-28T14:55:55.937 回答
3

这是一个有效的陈述。

因为 JavaScript 的引擎有所谓的 ASI(自动分号插入),它在必要时在行返回时插入分号。“如有必要”含糊不清;有时它有效,有时无效。见规则

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

return
{
};

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

所以不推荐用于return语句。

但是,如果您的指南推荐使用 Allman 样式进行函数声明,那就完全没问题了。我知道有些是这样的。

于 2012-06-28T15:00:51.843 回答
2

我认为这取决于声明。例如,如果左大括号在新行上,则返回语句可能会被破坏。 更多信息在这里

于 2012-06-28T14:58:47.267 回答
2
return {
    a: "A",
    b: "B"
};

// vs.

return // Semicolon automatically inserted here! Uh oh!
{
    a: "A",
    b: "B"
}
于 2012-06-28T14:58:56.533 回答
0

你可以使用 Allman 或 Allman-8 风格,只要你记住一个带有关键字return和的特殊情况throw

returnthrow由于ASI 规则throwandreturn语句有特殊例外,因此在 JavaScript 中将对象字面量与关键字换行符分开是行不通的:

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

注意以下是语法中唯一受限制的产生
式: [...]
ReturnStatement :
return [no LineTerminator here] Expression ;
ThrowStatement :
throw [这里没有 LineTerminator] 表达式

(也有其他受限制的产品,但它们不支持大括号,因此它们对于 Allman 风格并不重要。)

在实践中,这并不像您期望的那样工作

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,
};

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

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

于 2022-02-02T10:25:35.900 回答