Is It Necessary to Use Semicolons in JavaScript?

Is It Necessary to Use Semicolons in JavaScript?

Let’s start with two basic but very important ideas: 1) JavaScript is a flexible language, and 2) some semicolons in JavaScript are more needed than others. JavaScript sometimes gives us so much freedom that some practices end up being “optional”, and an example of this is the use—or lack of use—of certain semicolons.

To simplify the idea further, normally a missing semicolon won’t break your JavaScript code as it would in another programming language such as Java or the C family, but there’s a catch: Sometimes you can and will break your javascript code for a missing semicolon in the right (or wrong, maybe?) conditions.

How JavaScript works

Before diving into the fun part, a.k.a “how to break your code with the correct missing semicolon,” let’s take a moment to try to better understand how JavaScript as a programming language works in the background.

Compiled vs Interpreted

There are two types of programming languages: compiled and interpreted. Compiled languages need a compiler to turn written code into machine code that will be executed later. Some classic examples of this are languages such as C, C++, and Haskell. On the other side, interpreted languages such as Python or PHP (freecodecamp.org, 2020) are interpreted at runtime. Then we have JavaScript…a language that we cannot definitively classify as neither compiled nor interpreted.

JavaScript defies classification because at a very technical level it is compiled before being interpreted by the browser line by line. This can be tricky to understand and agree on; some classify JavaScript as an interpreted language. For example, this article from Stanford University explicitly states that “JavaScript is an interpreted language, not a compiled language,” and even the same article from freecodecamp.org referenced above classifies JavaScript as an interpreted language. Let’s not forget, however, that the code that is being interpreted by the browser was first compiled by the engine behind it. If we want to verify this information, we can reference the official V8 blog which states the following:

“With Ignition (the interpreter inside V8), V8 compiles JavaScript functions to a concise bytecode, which is between 50% to 25% the size of the equivalent baseline machine code. This bytecode is then executed by a high-performance interpreter which yields execution speeds on real-world websites close to those of code generated by V8’s existing baseline compiler.” (V8 official blog, 2016).

V8 is Google’s JavaScript engine on some browsers like Google Chrome (V8.dev), but if we still have some second thoughts on this whole compiled versus interpreted process, we can take a look at this illustration:

Finally, as we can see in the illustration, during the compile-time also happens something called “parsing”, a process that is in charge of “analyzing and converting a program into an internal format that a runtime environment can actually run” (MDN Docs, 2021), or in other words, this is the translation from the thing we have, into the thing we need to make it work in the browser. Knowing about the step of parsing during the compilation is necessary for you to understand the exact part of the execution that deals with the missing semicolons.

Automatic Semicolon Insertion (ASI)

Now that we know about the relationship between the compiling process, the parsing, and the interpretation of the code in the browser, we are ready to talk about something that happens during the parsing step called Automatic Semicolon Insertion (ASI).

This process inserts semicolons in some statements in the JavaScript code when we don’t do it ourselves. To be more precise these are the statements that will be updated by the ASI (MDN Docs, 2021):

  • Empty statement
  • Variable statement
  • Import & export
  • Expression statements
  • Debugger
  • Continue, break, throw & return

To clarify this idea a little bit more we can take a look at the next illustration with a few simple lines where we can see the before and after the ASI in our code:

There are three explicit rules in the JavaScript architecture for the Automatic Semicolon Insertion (ECMAScript, 2021) that we can keep in mind:

  1. When there is a line terminator that is not allowed.
  2. When the parser cannot parse the next line.
  3. When we have ++, –, continue, break, return, yield, yield* and module.

Again, as we can see on the documentation (ECMAScript, 2021) this is a simple way to represent and understand when the ASI works and when it does not:

But, if you’re still not sure about how true this is, you can reproduce it yourself on the browser’s console like this:

Only the first one didn’t work because of the missing semicolon that the ASI couldn’t add, but the same code with a line terminator (the code on the new line) did work because the ASI was able to fix it.

When to use semicolons

Now that we know that JavaScript automatically adds semicolons to certain statements with a few restrictions and rules, we can—as a best practice—use semicolons after finishing statements such as variable declaration with var, let, or const, when calling a function, using ++ or –, and when using return, break or continue.

Let’s wrap up the “semicolons in JavaScript” topic with some clear examples of when your code will break for a missing semicolon.

Example 1:

In this case, the missing semicolon on the declaration of variable c breaks the following toString function because its value is recognized as a non declared function. We can fix this error with a semicolon in the declaration of the last variable. (Flavio Copes, 2018)

Example 2:

In this case, the error is with the variable c, and that’s because, for JavaScript, the last piece of code is in the same line, it looks like this:

With that being said, we’re trying to use a variable that doesn’t exist yet, and again, the way to fix this behavior is with the almighty semicolon.

Final thoughts

JavaScript is a very flexible language, but that doesn’t mean that we only have to put forth the minimum effort to make it work. As a best practice, we should use standard conventions within our projects, and in these particular cases, that convention should include using semicolons because even if you don’t add them, the language needs them anyway and will try—but not always succeed—to fix them with ASI.

It is important to keep in mind two more things: First, it’s possible to have errors if you don’t use semicolons in your JavaScript file and try to minify or uglify it. Second, semicolons will not significantly affect the performance and size of your file (Fullstack Academy, 2017).

Your code will not always break due to a missing semicolon, but contrary to popular belief, JavaScript is relying on them in the background. As developers, it is our responsibility to understand the behind-scenes process of the tool we’re using.