Making Sense of Expressions, Statements, and Semicolons

by Gordon Zhu, February 2025

JavaScript programs are made up of 0 or more statements. You can think of a statement as a standalone instruction, which may or may not produce a value.

statement1
statement2
statement3
.
.
.

A statement may contain expressions, which are snippets of code that always produce a value.

// A statement without any expressions.
let nothing;

// A statement with the expression 10 + 10.
let number = 10 + 10;

// A statement composed of ONLY an expression.
'hello';

Since functions accept expressions as arguments, you can test if something is an expression by passing it into a function. If you don't get an error, you have an expression. For example, console.log(1) works because 1 is an expression.

Since a statement can be composed of an expression and nothing else, every expression on its own is a statement, but not every statement is an expression.

Venn Diagram of Statements and Expressions

A statement that can contain other statements is known as a block statement, or simply a block. Blocks are enclosed by { and }.

if (true) {
  statement1
  statement2
  statement3
  .
  .
  .
}

Semicolons

A semicolon should follow any statement that is not a block. As an example, if-statements, if...else statements, and function declarations are all block statements, and should not be followed by semicolons.

A note about functions

The only case where you will have a block followed by a semicolon is when you're using a function expression as part of a non-block statement.

// Using a function as part of an assignment.
let myFunction = function emptyFunction() {
  // block
};


function example() {
  // Using a function as part of a return statement.
  return function f() {};
}

A lot of people think this is sort of an exception, but it's actually not. Any statement that would normally end in a semicolon, will still end in a semicolon, even when a function is involved. So at a more general level, I think of it like this:

variableName = expression;

function f() {
  return expression;
}

In the above two examples, every expression should be followed by a semicolon. It does not matter one bit if the expression is a function.

Mistaking objects for blocks

Many beginners make the mistake of assuming object literals like {name: 'Gordon'} are blocks because they are also enclosed by { and }, but this is wrong. Remember, blocks can contain arbitrary statements. This is not true of objects, which can only contain key: value pairs.