I cannot remember where, but recently I passed a comment where the user told that 1TBS is more preferred than Allman in JavaScript and said Allman has dangerous implications in JavaScript.
Was it a valid statement? If so, why?
I cannot remember where, but recently I passed a comment where the user told that 1TBS is more preferred than Allman in JavaScript and said Allman has dangerous implications in JavaScript.
Was it a valid statement? If so, why?
return
cannot have LineTerminator
after it so:
return
{
};
is treated as return;
(return undefined
) instead of return {};
(return an object)
See the rules for Automatic Semicolon Insertion (ASI)
for more.
Semicolons are required in JavaScript; they’re just not required in YOUR JavaScript.
–
Kyl return
statement. If you return with a named variable there will be no problems. You can use full Allman style everywhere else and I'd claim that using syntax return response
is more readable than return { foo:bar, zoo: 1}
anyway. –
Cypher It is a valid statement.
Because JavaScript's engines have what's called ASI (Automatic Semicolon Insertion) which inserts a semicolon if necessary at lines returns. The "if necessary" is ambiguous; sometimes it works and sometimes doesn't. See the rules.
So, as said in the other answers:
return
{
};
// Is read by the JavaScript engine, after ASI, as:
return; // returns undefined
{ // so this is not even executed
};
So it's not recommended for return
statements.
However, if your guidelines recommend the Allman style for function declarations, it's perfectly fine. I know some that do.
return {
a: "A",
b: "B"
};
// vs.
return // Semicolon automatically inserted here! Uh oh!
{
a: "A",
b: "B"
}
I think it depends on the statement. For example a return statement might be broken if opening brace is on new line. More info here.
You can use Allman or Allman-8 style just fine as long as you remember one special case with keywords return
and throw
.
Separating object literals from keywords return
or throw
by a linefeed doesn't work in JavaScript because of ASI rules which have a special exception for throw
and return
statements:
- When, as the program is parsed from left to right, a token is encountered that is allowed by some production of the grammar, but the production is a restricted production and the token would be the first token for a terminal or nonterminal immediately following the annotation “[no LineTerminator here]” within the restricted production (and therefore such a token is called a restricted token), and the restricted token is separated from the previous token by at least one LineTerminator, then a semicolon is automatically inserted before the restricted token.
and
NOTE The following are the only restricted productions in the grammar:
[...]
ReturnStatement :
return
[no LineTerminator here] Expression ;
ThrowStatement :
throw
[no LineTerminator here] Expression ;
(There are other restricted productions, too, but those don't support braces so they are not important for Allman style.)
In practice, this doesn't work as you would expect:
return
{
status: "successful",
user:
{
id: "9abf38a3-c2f5-4159-a1be-0eccbc1b2349",
label: "John Doe",
},
};
because it will be interpreted as (note the semicolon after return!)
return;
{
status: "successful",
user:
{
id: "9abf38a3-c2f5-4159-a1be-0eccbc1b2349",
label: "John Doe",
},
};
So, you have to either use syntax
const response =
{
status: "successful",
user:
{
id: "9abf38a3-c2f5-4159-a1be-0eccbc1b2349",
label: "John Doe",
},
};
return response;
or
return {
status: "successful",
user:
{
id: "9abf38a3-c2f5-4159-a1be-0eccbc1b2349",
label: "John Doe",
},
};
instead.
I personally think that naming the returned structures is more readable in any case, so I use that. I also use Allman-8 everywhere which practically means that you use 8 space width tab characters and indent everything with a single tab character instead of 1 or more spaces.
In theory, somebody could also write
throw
{
status: "error",
code: 12,
details: localvar,
};
which would also fail because a semicolon would be inserted immediately after the keyword throw
because of the ASI rules above. In real world, everybody seems to write throw new ...
or throw localvar
.
I don't know the history for these exceptions but I can only assume it's some historical mishap that cannot be fixed anymore because of existing real world code depending on this mishap. I fail to see any construct where this automatic semicolon would actually be beneficial so I think this is just a bug in historical specification. (The code following return
or throw
cannot reasonably start with an object literal so it wouldn't work anyway with the inserted semicolon.)
Update year 2024:
I'm nowadays using Allman style where I differentiate between code blocks and object literals. I start all object literals on the same line as the containing statement and all code blocks on a next line. This simple rule also handles the special cases of return
and throw
as a side effect.
And as a bonus, it makes two different meanings of {
visually different. I personally prefer code where understanding it doesn't require back-tracking while reading the code. If you put the opening brace of both code blocks and object literals on the next line, both will look identical but the meaning is totally different.
© 2022 - 2024 — McMap. All rights reserved.