我不记得在哪里,但最近我传递了一条评论,其中用户告诉 1TBS 在 JavaScript 中比 Allman 更受欢迎,并说 Allman 在 JavaScript 中具有危险的含义。
这是一个有效的陈述吗?如果是这样,为什么?
我不记得在哪里,但最近我传递了一条评论,其中用户告诉 1TBS 在 JavaScript 中比 Allman 更受欢迎,并说 Allman 在 JavaScript 中具有危险的含义。
这是一个有效的陈述吗?如果是这样,为什么?
return
不能有LineTerminator
这样的:
return
{
};
被视为return;
(return undefined
) 而不是return {};
(return an object)
有关更多信息,请参阅规则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 {
a: "A",
b: "B"
};
// vs.
return // Semicolon automatically inserted here! Uh oh!
{
a: "A",
b: "B"
}
你可以使用 Allman 或 Allman-8 风格,只要你记住一个带有关键字return
和的特殊情况throw
。
return
throw
由于ASI 规则对throw
andreturn
语句有特殊例外,因此在 JavaScript 中将对象字面量与关键字或换行符分开是行不通的:
- 当程序从左到右解析时,遇到某个语法产生式允许的记号,但产生式是受限制的产生式,并且该记号将是紧跟注释之后的终端或非终端的第一个记号“<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
。
我不知道这些异常的历史,但我只能假设这是一些历史事故,由于现有的现实世界代码取决于这种事故,因此无法再修复。我看不到任何这种自动分号实际上有益的结构,所以我认为这只是历史规范中的一个错误。(后面的代码return
或throw
不能合理地以对象文字开头,因此无论如何它都不能与插入的分号一起工作。)