Semicolon Rules in JavaScript are weird...

dean

dean

Posted on September 17, 2018

Semicolon Rules in JavaScript are weird...

I'd like to preface this with that I really do like JavaScript. It has quirks, although most of them are edge cases that you won't encounter. But I just found one that I'm still confused, and I'd rather not look up the JavaScript spec just to figure this out...

My original function:

function cubicBezier(x, u0, u1, u2, u3) {
    return
        u0 * (1 - x) * (1 - x) * (1 - x) +
        u1 * (1 - x) * (1 - x) * x +
        u2 * (1 - x) * x * x +
        u3 * x * x * x;
}
Enter fullscreen mode Exit fullscreen mode

Some of you seasoned JavaScript experts might see this and go "it will always return undefined", because the return is interpreted as return; since nothing else follows. This got me wondering about semicolon rules in JavaScript.

My favorite programming language is Go, which also has optional semicolons. The semicolon rules are extremely simple in Go:

When the input is broken into tokens, a semicolon is automatically inserted into the token stream immediately after a line's final token if that token is

  • an identifier
  • an integer, floating-point, imaginary, rune, or string literal
  • one of the keywords break, continue, fallthrough, or return
  • one of the operators and punctuation ++, --, ), ], or }

By the way, Go's rules can be interpreted a lot easier like this:

A semicolon is placed if the line ends with:

  • a letter or number
  • a closing punctuation mark (aka ], ), }, and closing "/')
  • ++ or --

I thought that JavaScript Semicolon rules were just as simple as Go's when I saw the function return undefined. After all, nothing appears after the return, so a semicolon was placed afterward. It is that simple right?

Well, I looked into it further.

So I made a few functions for adding 1 to an integer to see what JavaScript did.

function addOneNormal(x) {
    return x + 1
}

function addOneWeird(x) {
    return x
        +1
}

function addOneUndefined(x) {
    return
        x + 1
}
Enter fullscreen mode Exit fullscreen mode

We know what addOneNormal and addOneUndefined end up being. addOneNormal adds one to x, and addOneUndefined hits the return and returns undefined. So what does addOneWeird do?

(sidenote: in Go, this is very simple, as return x ends with a letter, so a semicolon is placed. The next line, +1, results in a compile error as +1 is not being assigned to anything)

Well, some people would expect it to be the same as return x + 1;, although some people (like me) see it as return x; +1;, where the +1 is a 1 with a unary plus operator before it.

The result

So what was the result? addOneWeird(5) => 6. It added 1 successfully. That's weird... isn't it? That statement looked at the next line, even though a bare return didn't.

Unfortunately these rules cannot be made more consistent, as backward-compatibility is a requirement in JavaScript.

Anyway, could someone explain why the + operator ended up being interpreted as a binary plus rather than a unary plus in this case? If the addOneUndefined function resulted in undefined, It seems more logical foraddOneWeird to be interpreted as return x; +1;.

💖 💪 🙅 🚩
dean
dean

Posted on September 17, 2018

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related