JavaScript semicolons are not required but have been a topic of debate among developers. While some prefer using semicolons in their code, others choose to avoid them.
Personally, I used to rely on semicolons for years until the fall of 2017, when I decided to experiment with omitting them. I configured Prettier, an automated code formatter, to remove semicolons from my code unless they were necessary for specific language constructs.
Over time, I have found that omitting semicolons makes my code look cleaner and more readable. The reason we can omit semicolons is because JavaScript has a mechanism called Automatic Semicolon Insertion that adds them behind the scenes when necessary.
To prevent unexpected behavior caused by Automatic Semicolon Insertion, it is important to understand the rules that govern its behavior. These rules determine when a semicolon will be automatically inserted:
- When the next line of code would break the current line (code can span multiple lines).
- When the next line starts with a closing curly brace (
}
), indicating the end of a code block. - When the end of the source code file is reached.
- When a
return
statement appears on its own line. - When a
break
statement appears on its own line. - When a
throw
statement appears on its own line. - When a
continue
statement appears on its own line.
Here are some examples of code that may not behave as expected due to Automatic Semicolon Insertion:
- The code snippet:
const hey = 'hey'
const you = 'hey'
const heyYou = hey + ' ' + you
['h', 'e', 'y'].forEach((letter) => console.log(letter))
Will generate an error Uncaught TypeError: Cannot read property 'forEach' of undefined
. This is because, according to rule 1, JavaScript interprets the code as:
const hey = 'hey';
const you = 'hey';
const heyYou = hey + ' ' + you['h', 'e', 'y'].forEach((letter) => console.log(letter))
- The code snippet:
(1 + 2).toString()
Will output "3"
.
However, the code snippet:
const a = 1
const b = 2
const c = a + b
(a + b).toString()
Will raise a TypeError: b is not a function
exception because JavaScript interprets it as:
const a = 1
const b = 2
const c = a + b(a + b).toString()
- The code snippet:
(() => {
return
{
color: 'white'
}
})()
Will not return an object with the color
property as expected. Instead, it will return undefined
because JavaScript automatically inserts a semicolon after the return
statement. To fix this, the opening bracket should follow immediately after the return
statement:
(() => {
return {
color: 'white'
}
})()
- The code snippet:
1 + 1
-1 + 1 === 0 ? alert(0) : alert(2)
Will display 2
in the alert instead of 0
. This is because JavaScript, based on rule 1, interprets it as:
1 + 1 -1 + 1 === 0 ? alert(0) : alert(2)
In conclusion, the use of semicolons in JavaScript is a matter of personal preference. It is important to understand the rules of Automatic Semicolon Insertion to avoid bugs caused by unexpected behavior. Here are some guidelines:
- Be cautious with
return
,break
,throw
, andcontinue
statements. Always put them on the same line. - Avoid starting a line with parentheses as they may be concatenated with the previous line, resulting in a function call or array element reference.
Ultimately, it is essential to thoroughly test your code to ensure it behaves as expected.