Javascript's not very optional "optional semicolons"
It's something we all hear about: Javascript's semicolons are optional except when they aren't. But it's actually kinda surprising how many people haven't encountered what this is referring to. So I thought I would share a real example encountered by Jr. Dev at work (well an example snippet version of what they encountered, NDAs gotta be followed and all that).
So for various reasons they needed to set up an anonymous async function and use a then to attach an async callback. They ended up with something like this:
console.log("I am a line of code that works") (async () => { console.log("I'm doing some async things") await new Promise(resolve => setTimeout(resolve, 1000)); })().then(() => { console.log("Done!") })
It's a clever little construction actually. But what's weird is that there's now an error on the first line (Firefox):
Uncaught TypeError: console.log(...) is not a function
Why is the line before borked? Like it'd make sense if the weird async bit had an error, but no, it's the entirely normal console.log call.
Well it's because Javascript doesn't always treat whitespace the same. When something is in brackets Javascript gives 0 hoots about the whitespace between it and the previous token. So what the interpreter is actually seeing is this:
console.log(...)(...).then(...)
It thinks you are trying to call the result of console.log and attach an async callback to the result of that. console.log 'returns' undefined. undefined is not a function. Hence the error "console.log(...) is not a function".
The way to solve this is to add the good ol' "optional" semicolon back into the code like this:
console.log("I am a line of code that works"); (async () => { ...
Now the interpreter knows that the first line is a complete statement, and it will no longer think you are trying to call it as a function.
Don't forget your semicolons, people!












