我不记得在哪里了,但最近我发表了一条评论,用户告诉 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"
}
只要您记住一个带有关键字 return
和 throw
的特殊情况,您就可以使用 Allman 或 Allman-8 样式。
将对象文字与通过换行符return
或throw
的关键字分开在 JavaScript 中不起作用,因为 ASI 规则对 throw
和 return
语句有一个特殊的例外:
- 当程序从左到右解析时,遇到语法的某些生产所允许的标记,但是生产是受限制的生产,代币将是第一个紧跟在限制生产中的注释"[此处没有线路终结者]"(因此这样的令牌称为受限令牌),并且受限令牌与上一个令牌之间至少隔一个行终止符,然后在受限令牌。
和
注意 以下是语法:
[...]返回声明:
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
。
我不知道这些异常的历史,但我只能假设这是一些历史事故,由于现有的现实世界代码依赖于这种事故,因此无法再修复。我没有看到任何这种自动分号实际上有益的结构,所以我认为这只是历史规范中的一个错误。(return
或throw
后面的代码不能合理地以对象文字开头,因此它无论如何都不适用于插入的分号。