5

I just ran into a problem where I did:

return
    isSomething() &&
    isSomethingElse();

Which doesn't work because JavaScript inserts the semicolon after the return making the above equivalent to:

return;
isSomething() && isSomethingElse();

This totally baffled me as to why it does this. I found some Stack Overflow questions about the topic (e.g. this, this, and this) but they just explain when it does this, referring to the specs.

I can't even imagine a situation where I would want to have a return; statement followed by some other valid JavaScript statements (unless you use goto or maybe some other obscure JavaScript I haven't heard of). In my opinion, this can only cause problems.

What I'm wondering is why it does this. Why is this part of the spec?

Concerning the close as duplicate. I think I clearly stated that I read other questions and answers stating that it's part of the JavaScript spec and even put the part that distinguishes my question from the others in bold. The question that is linked in the close reason does not contain an answer to this question and is of the exact same form as the other three questions I linked as not answering my question.

double-beep
  • 3,889
  • 12
  • 24
  • 35
Matthijs Wessels
  • 6,234
  • 6
  • 54
  • 97
  • 2
    One might ask why you would write the code out that way in the first place. – Kai Qing May 14 '14 at 01:56
  • 1
    _“I can't even imagine a situation where I would want to have a return; statement followed by some other valid javascript statements”_ – in that case where your `return` is dependent on an `if`, and you leave out the curly parentheses as well maybe … but _“this can only cause problems”_ :-) – CBroe May 14 '14 at 01:58
  • @Kai say I have a lot more clauses that I want to align with one indent. – Matthijs Wessels May 14 '14 at 01:59
  • 3
    Because that's what needs to happen. Because sometimes... the truth isn't good enough. Sometimes people don't deserve more. Sometimes people don't deserve to have their faith rewarded. Because this is the Javascript Gotham deserves, but not the one it needs right now. – Mike H-R May 14 '14 at 01:59
  • Worth reading [An Open Letter to JavaScript Leaders Regarding Semicolons](http://blog.izs.me/post/2353458699/an-open-letter-to-javascript-leaders-regarding) and [JavaScript Semicolon Insertion - Everything you need to know](http://inimino.org/~inimino/blog/javascript_semicolons) – jfriend00 May 14 '14 at 02:00
  • Sometimes you just want a function to return so it stops executing. Just put the `return` on the same line as the `isSomething()` and you`ll be fine. – StackSlave May 14 '14 at 02:07
  • @CBroe ah yes, that would actually be a valid scenario. – Matthijs Wessels May 14 '14 at 02:09
  • @MatthijsWessels -- if you have so many functions you need to indent them in ways that are breaking the language, maybe refactor them into a single method which can be evaluated in the return? – Sam Hanley May 14 '14 at 02:09
  • @PHPglue: _“Sometimes you just want a function to return so it stops executing”_ – which you could still do with `return;` _with_ an explicit semicolon … so that argument still doesn’t justify this arbitrary behavior of JS in this point IMHO. // I think there is no _real_ point in actually discussing this (apart from for the fun of it) – it’s just one of those things we have to accept as “a given” without any real solid logic behind it. – CBroe May 14 '14 at 02:14
  • @sphanley what do you think is the purpose of the function to which this return statement belongs :). If the function names are a bit longer and are part of an object with a relatively long name as well as having to write `this` in front of each call due to the object being a private member of a class (say I'm using TypeScript): then three clauses can already make you want to indent. – Matthijs Wessels May 14 '14 at 02:18
  • 1
    _“then three clauses can already make you want to indent”_ – well, then use `return ( [as many line breaks between further expressions as you want] );`, and the issue is dealt with :-) – CBroe May 14 '14 at 02:22
  • @CBroe that's actually not a bad idea! – Matthijs Wessels May 14 '14 at 02:25
  • … and could in the end lead to a new JS coding convention, “_always_ use parentheses after return, because you never know when you might want to expand a one-line statement into multiple lines, and might forget about the implications of doing so”, similar to what we already have with `if` and the curly braces … (and no, I can’t actually tell you whether I’m _seriously_ considering this right now or not :-) – CBroe May 14 '14 at 02:29

3 Answers3

4

The exact reasons why are probably lost in the mists of time. I'm willing to bet that it happened something like this:

  • At some point, somebody thought it would be a good idea to make semicolons optional at the end of statements.
  • Later on, somebody else noticed an ambiguity in the syntax when semicolons were omitted when used with return statements in the way you describe.
  • The formal language specification was then amended with the confusing new rule about omitted semicolons on return statements, to codify current practice rather than changing the rules to make sense.
Greg Hewgill
  • 828,234
  • 170
  • 1,097
  • 1,237
  • 4
    Seems like as good a guess as any as to what actually happened unless Brendan Eich wants to drop by and tell us what really happened. – jfriend00 May 14 '14 at 02:05
  • 1
    The time between "at some point" and "later on" might have been a lot shorter than you think (perhaps a few minutes). I expect the formal language specification came much, much later given that automatic semicolon insertion is part of [ECMA-262 ed 1](http://www.ecma-international.org/publications/files/ECMA-ST-ARCH/ECMA-262,%201st%20edition,%20June%201997.pdf) (June 1997, nearly 2 years after *LiveScript* first shipped in a browser in September 1995). – RobG May 14 '14 at 02:50
1

Javascript has this "clever" feature which makes it so that the semicolon is generally optional in your code. If you leave the semicolons off the end of the line, it will add them to the line endings. As per the codeacademy article on the subject:

The semicolon is only obligatory when you have two or more statements on the same line:

var i = 0; i++        // <-- semicolon obligatory
                      //     (but optional before newline)
var i = 0             // <-- semicolon optional
    i++               // <-- semicolon optional

So basically, you can't break your code across multiple lines like that, because Javascript thinks it's smart enough decide you forgot the semicolons and insert them for you.

Sam Hanley
  • 4,498
  • 7
  • 32
  • 56
  • Yes, but by that logic you might argue that `var val = 5 [line break] + 4;` might result in the variable having the value 5 afterwards, which it doesn’t. (And yes, a “stand-alone” `+ 4` would be a valid expression on its own.) – CBroe May 14 '14 at 02:03
  • Well I'd say that even though `+ 4` is a valid expression, Javascript is smart enough to infer that nobody's going to use `+ 4` as a standalone expression. I don't know why, but the linked article is a good explanation of how it's supposed to work. – Sam Hanley May 14 '14 at 02:07
  • _“The semicolon is only obligatory when you have two or more statements on the same line”_ – well, with `return [line break] val;` you don’t, and it will still yield `undefined` even though `val` is a defined variable with a value. Sorry, but no amount of arguments of that quality will convince me that this particular behavior is _not_ just arbitrary and of the “because we said so, that’s why” variety :-) – CBroe May 14 '14 at 02:11
  • I don't see how you're seeing the second example as inconsistent -- since the semicolon isn't obligatory in that situation, it's assuming that there should be one at the end of the line, and terminating the return. I agree that the `var val = 5 [line break] + 4;` example doesn't make sense, but with `return [line break] val;`, it's doing what it says -- assuming you left out an non-obligatory semicolon. – Sam Hanley May 14 '14 at 02:15
  • _“since the semicolon isn't obligatory in that situation, it's assuming that there should be one at the end of the line”_ – well that _is_ the inconsistency, isn’t it? `return [line break] val;` – who says there _should_ be one, whereas in `var val = 5 [line break] + 4;` “they” don’t say so? (Well, the “who” is clear, the guys who wrote the spec – but their _why_ is questionable and beyond any _consistent_ logic.) – CBroe May 14 '14 at 02:19
  • By no means am I trying to say that it isn't broken. For some reason they've decided that referencing a variable is seen as a separate expression, while something like `+ 4` isn't. As to why -- yeah, it's going to just have to be one of those things that boils down to "because it's got to work some way, and this is the way it does". – Sam Hanley May 14 '14 at 02:22
-2

This is a "feature", not a bug.

Semicolons in Javascript are optional.

SLaks
  • 800,742
  • 167
  • 1,811
  • 1,896
  • 4
    The point of the OP's question is that it's a feature that leads to inadvertent problems. So, why would they put in a feature that can so easily confuse. – jfriend00 May 14 '14 at 02:06