About Semicolons in Javascript

About Semicolons in Javascript

When I first started writing JavaScript I thought that semicolons were mandatory. I was learning about jQuery at the time and all of the documentation I was reading showed a semicolon at the end of every statement.

When I first started writing JavaScript I thought that semicolons were mandatory. I was learning about jQuery at the time and all of the documentation I was reading showed a semicolon at the end of every statement.

I had a bit of background in some other programming languages and this was consistent with what I already knew — semicolons are there to help the computer distinguish one instruction from another. Makes sense.

It wasn’t long before I learned about JavaScript’s Automatic Semicolon Insertion (ASI). Basically, JavaScript will put semicolons in for you automatically if you leave them out. So, they aren’t mandatory after all.

The history behind this is interesting. JavaScript didn’t start out as the programming language heavyweight that it is today. In the beginning, it was intended to be something that non-professionals could pick up without too much trouble. ASI was a feature thrown in to make the language more friendly to laymen. At least, that was the idea.

To avoid breaking the internet, JavaScript needs to be backward compatible. We can add new features (ES6, ES7, ES8, etc) but we can’t take features away because they’re already being used and relied on. Whether intentionally or by accident, millions of lines of JavaScript exist that need ASI to work properly. So, we’re all stuck with it, but some of us choose to handle it in different ways.

One camp writes code that includes semicolons. Their code looks a bit more like a language that actually requires semicolons, like C or PHP.

The other camp leaves the semicolons off, relying on ASI to put them in automatically. Their code looks slightly more like Python or Ruby.

The JavaScript community is still split on this. For example, React still includes semicolons in its docs, but Vue does not.

Vue was my next stop in JavaScript frameworks after jQuery and React, and I decided to adopt the no-semicolon coding style featured in the docs. I enjoyed it (it makes your code look so much cleaner!) and began applying that style to other JavaScript endeavors outside of Vue — Node.js, for instance.

Unfortunately, I started running into problems…

How Relying on Automatic Semicolon Insertion Breaks Things: A Concrete Example

I wanted to automate end-to-end testing for a project I was working on. My idea was to program a basic bot that would go to my webpage and put different kinds of input into a form. If the output the bot gets back is what I expected, good. If not, I might have a bug.

Puppeteer (Headless Chrome Node.js API) seemed to be a good way to do this, so I took it for a spin. The docs feature this snippet of code to get you started:

const puppeteer = require('puppeteer');
(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  await page.goto('https://example.com');
  await page.screenshot({path: 'example.png'});
  await browser.close();
})();

Essentially, the idea with this code is to import Puppeteer and then implement anasync IIFE (Immediately Invoked Function Expression). This allows you to use the await keyword to wait for asynchronous actions (like launching a browser, for example) to complete before starting on to the next step (loading a webpage, for example).

Testing this out, everything works. Puppeteer goes to the webpage and takes the screenshot as expected. Awesome.

But the rest of the code I had written for this project was done in the sans-semicolon style. So, for consistency, I took the semicolons out:

const puppeteer = require('puppeteer')
(async () => {
  const browser = await puppeteer.launch()
  const page = await browser.newPage()
  await page.goto('https://example.com')
  await page.screenshot({path: 'example.png'})
await browser.close()
})()

Unfortunately, this change caused my code to throw an error that it wasn’t throwing when the semicolons were included:

/Users/chris/Documents/code/sandbox/nodejs/puppeteer-test/index.js:3
(async () => {
^
TypeError: require(...) is not a function

This was confusing. The code was working fine — and then it wasn’t. But after digging around a bit, it started to make sense.

Node.js doesn’t know that it should stop after const puppeteer = require('puppeteer') —because it doesn’t have a semicolon to go by. Instead, it sees an opening brace coming up below and interprets that to be a function call. It sees the code as something like this:

const puppeteer = require('puppeteer')(async () => {
  const browser = await puppeteer.launch()
  const page = await browser.newPage()
  await page.goto('https://example.com')
  await page.screenshot({path: 'example.png'})
await browser.close()
})()

Without semicolons, this code is ambiguous.

This is a big problem for the sans-semicolon camp. IIFEs are a common pattern in JavaScript, not an obscure edge case, and our code styling needs to work with them. Avoiding IIFEs just to avoid semicolons would be pretty silly.

Situations like this don’t come up a lot — but they do sometimes and JavaScript developers should be prepared for them.

It’s possible to only insert semicolons when they’re absolutely necessary (for example after the require statement above), but this is awkward for a couple of reasons:

  • You might not always know where semicolons are required beforehand. In fact, when things break, you might not know you are dealing with an ASI problem at all. Including semicolons by default can potentially save you a lot of time spent debugging.
  • It just looks wrong to have semicolons in some places and not in others — My OCD can’t deal with that kind of inconsistency.

Another solution is to abide by different rules depending on your current environment. Go with the flow, so to speak.

For example, you might include semicolons when you are writing vanilla JavaScript, jQuery, and Node.js and leave the semicolons off when you write React and Vue. The inconsistency still bugs me, but I prefer this solution over the one mentioned above.

Finally, we could simply put semicolons everywhere, all the time. As much as I love the look of JavaScript without semicolons, including semicolons by default makes a lot of sense.

Summary

For better or worse, JavaScript was originally designed to include Automatic Semicolon Insertion (ASI) and we are stuck with it.

It has been almost 25 years since the language was invented and the community has still not reached consensus on semicolon best practices. Some devs like to include them, some devs like to leave them off.

Whatever camp you fall into, it’s important to understand that omitting semicolons can bite you from time to time, and you might not expect it. IIFEs, for example, can be a problematic pattern for sans-semicolon users.

In the end, semicolons aren’t exactly mandatory, but they aren’t exactly optional, either.

Programming a Javascript Simon Game Tutorial

Programming a Javascript Simon Game Tutorial

In this javascript tutorial, I recorded myself live programming an html5 javascript simon game.

In this javascript tutorial, I recorded myself live programming an html5 javascript simon game.

For those who don't know, I'm a full stack web developer who has been in the industry for over 5 years now. There is a lot of things I have learned along the way and I'd like to share that knowledge with anyone wanting to learn!

like this video if you found it useful and would like to see more videos of the same content.

subscribe to my channel if you are trying to improve your abilities as a web developer, software engineer, or even if you are just learning to code.

Don't forget to turn on those bell notifications!

Understanding Memoization And Dynamic Programming in Javascript

Understanding Memoization And Dynamic Programming in Javascript

In this Javascript tutorial I will explain what memoization is, how to use it, when you should use memoization, how to use memoization, what dynamic programming is, how to use memoization in dynamic programming. Memoization is a big complicated word that you may have never even heard before, but you may be surprised to know that you are most likely already using memoization without even realizing it.

Memoization is a big complicated word that you may have never even heard before, but you may be surprised to know that you are most likely already using memoization without even realizing it. Memoization is just the act of caching values so that they can be calculated quicker in the future. Memoization is really useful in all parts of programming, but where it is most useful is in dynamic programming. In this video I will explain what memoization is, how to use it, and why it is so useful especially in dynamic programming.

🧠 Concepts Covered:

  • What memoization is
  • When you should use memoization
  • How to use memoization
  • What dynamic programming is
  • How to use memoization in dynamic programming

JavaScript Tutorial: if-else Statement in JavaScript

JavaScript Tutorial: if-else Statement in JavaScript

This JavaScript tutorial is a step by step guide on JavaScript If Else Statements. Learn how to use If Else in javascript and also JavaScript If Else Statements. if-else Statement in JavaScript. JavaScript's conditional statements: if; if-else; nested-if; if-else-if. These statements allow you to control the flow of your program's execution based upon conditions known only during run time.

Decision Making in programming is similar to decision making in real life. In programming also we face some situations where we want a certain block of code to be executed when some condition is fulfilled.
A programming language uses control statements to control the flow of execution of the program based on certain conditions. These are used to cause the flow of execution to advance and branch based on changes to the state of a program.

JavaScript’s conditional statements:

  • if
  • if-else
  • nested-if
  • if-else-if

These statements allow you to control the flow of your program’s execution based upon conditions known only during run time.

  • if: if statement is the most simple decision making statement. It is used to decide whether a certain statement or block of statements will be executed or not i.e if a certain condition is true then a block of statement is executed otherwise not.
    Syntax:
if(condition) 
{
   // Statements to execute if
   // condition is true
}

Here, condition after evaluation will be either true or false. if statement accepts boolean values – if the value is true then it will execute the block of statements under it.
If we do not provide the curly braces ‘{‘ and ‘}’ after if( condition ) then by default if statement will consider the immediate one statement to be inside its block. For example,

if(condition)
   statement1;
   statement2;

// Here if the condition is true, if block 
// will consider only statement1 to be inside 
// its block.

Flow chart:

Example:

<script type = "text/javaScript"> 

// JavaScript program to illustrate If statement 

var i = 10; 

if (i > 15) 
document.write("10 is less than 15"); 

// This statement will be executed 
// as if considers one statement by default 
document.write("I am Not in if"); 

< /script> 

Output:

I am Not in if
  • if-else: The if statement alone tells us that if a condition is true it will execute a block of statements and if the condition is false it won’t. But what if we want to do something else if the condition is false. Here comes the else statement. We can use the else statement with if statement to execute a block of code when the condition is false.
    Syntax:
if (condition)
{
    // Executes this block if
    // condition is true
}
else
{
    // Executes this block if
    // condition is false
}


Example:

<script type = "text/javaScript"> 

// JavaScript program to illustrate If-else statement 

var i = 10; 

if (i < 15) 
document.write("10 is less than 15"); 
else
document.write("I am Not in if"); 

< /script> 

Output:

i is smaller than 15
  • nested-if A nested if is an if statement that is the target of another if or else. Nested if statements means an if statement inside an if statement. Yes, JavaScript allows us to nest if statements within if statements. i.e, we can place an if statement inside another if statement.
    Syntax:
if (condition1) 
{
   // Executes when condition1 is true
   if (condition2) 
   {
      // Executes when condition2 is true
   }
}

Example:

<script type = "text/javaScript"> 

// JavaScript program to illustrate nested-if statement 

var i = 10; 

if (i == 10) { 

// First if statement 
if (i < 15) 
	document.write("i is smaller than 15"); 

// Nested - if statement 
// Will only be executed if statement above 
// it is true 
if (i < 12) 
	document.write("i is smaller than 12 too"); 
else
	document.write("i is greater than 15"); 
} 
< /script> 

Output:

i is smaller than 15
i is smaller than 12 too
  • if-else-if ladder Here, a user can decide among multiple options.The if statements are executed from the top down. As soon as one of the conditions controlling the if is true, the statement associated with that if is executed, and the rest of the ladder is bypassed. If none of the conditions is true, then the final else statement will be executed.
if (condition)
    statement;
else if (condition)
    statement;
.
.
else
    statement;


Example:

<script type = "text/javaScript"> 
// JavaScript program to illustrate nested-if statement 

var i = 20; 

if (i == 10) 
document.wrte("i is 10"); 
else if (i == 15) 
document.wrte("i is 15"); 
else if (i == 20) 
document.wrte("i is 20"); 
else
document.wrte("i is not present"); 
< /script> 

Output:

i is 20