cf.completefrontendCode editorOpen lab
THE JAVASCRIPT FIELD GUIDE

Statements, comments & semicolons

Learn how JavaScript reads code line by line: statements, expressions, blocks, semicolons, comments, and the whitespace rules that matter.

By the end, you can
  • 01
    Read code as instructionsTell statements from expressions and trace their completion values.
  • 02
    Group code safelyUse blocks, recognize labels, and return object literals from arrow functions.
  • 03
    Avoid formatting trapsUse semicolons, comments, and whitespace intentionally.

How JavaScript reads your code

A JavaScript file is not a cloud of symbols. It is a sequence of instructions read from top to bottom. Earlier you met the idea that a program is a recipe: a list of steps run in order. This lesson zooms in on the shape of those steps: statements, the value-producing pieces inside them called expressions, the braces that group steps, and the punctuation and spacing that make the recipe unambiguous.

You will see tiny programs first, then the traps professional developers still watch for: return on its own line, a missing semicolon before [, a stray semicolon after if, and braces that look like an object but start a block.

Real-life analogyStatements are sentences; expressions are phrases

Think of a statement as a complete sentence: it tells JavaScript to do one thing. An expression is more like a phrase: it produces a value that can be used inside a larger sentence. The phrase 2 + 3 becomes the value 5; the statement let score = 2 + 3; stores that value in a name.

In real life: A complete sentence: “Put the mug on the table.”
In JavaScript: A statement: let score = 5;
In real life: A phrase: “the blue mug”
In JavaScript: An expression: 2 + 3, score, or x > 2
In real life: A phrase can sit inside a sentence
In JavaScript: An expression can sit inside a statement

Where the analogy stops: Human sentences can be fuzzy and poetic. JavaScript grammar is strict: the engine must be able to parse one exact structure.

Tiny definition

A statement is a complete instruction. An expression is code that produces a value. A statement may contain expressions, and an expression can be used as a statement when you care about its side effect.

Statements vs expressions

INTERACTIVE

The fastest test is a question. For an expression, ask: what value does this produce? For a statement, ask: what instruction does this give? The same line can contain both. In let x = 5 + 3;, the whole line is a declaration statement, while 5 + 3 is an expression inside it.

How to tell JavaScript pieces apart
PieceQuestion to askTiny exampleWhat JavaScript gets
ExpressionWhat value does this produce?2 + 2The value 4
StatementWhat instruction does this give?let total = 4;A completed step in the program
Block statementWhich statements are grouped?{ console.log(total); }A group that runs in order
CommentWhat note helps humans?// explain whyNothing at runtime

Sort these cards. Pay special attention to console.log("hi"): the call expression produces a value, but we normally write the whole line for its side effect, printing.

Statement or expression?
  • let x = 5;
  • 5 + 3
  • x > 2
  • if (x) {}
  • "hello"
  • for (...) {}
  • console.log("hi");
  • ;
Try it yourself
0 of 8 correct

Place each card where it belongs. If a call expression is being used as a whole line for its side effect, choose expression used as statement.

Choose a category for every card. You can change an answer at any time; Reset clears them all.

This distinction matters because later lessons build on it. Conditions in if statements are expressions. The body of an if is a statement. The line "use strict"; in the next lesson is a special expression statement called a directive.

Expression statements and the empty statement

STEP THROUGH

JavaScript allows some expressions to stand alone as statements. A bare score; line is legal, although it is rarely useful in a program. A call such as console.log(score); is useful because calling it prints something. A lone semicolon is also legal: it is the empty statement, a complete instruction that intentionally does nothing.

Step through statements and expressions
Step 0 of 4Ready
Your turn: follow the blue line

Statements are complete instructions. Expressions are the value-producing pieces that can live inside those instructions.

Running in
  1. script
Next: line 1
Click the blue line to take the next stepPop out in the code editor (opens in a new tab)JavaScript
score;console.log("score:", score);;
CallStoreChangeResultRun = next line. Ran = already executed.
Recent returnsNothing yet. Start with the blue line.
A guided replay recorded from real JavaScript calls, not an engine debugger. Step follows executed statements; Back reviews a snapshot. Reset starts a fresh run.

The player mentions completion values. When a script evaluates a statement, JavaScript internally tracks a completion. Browser consoles and Node's vm.runInContext can show that value, but it is separate from printed output. console.log prints because of a side effect; its own result is undefined.

The empty statement is tiny but sharp

; by itself does nothing. That sounds harmless, until you accidentally write if (isReady);. Then the if controls the empty statement, and the block after it runs every time. You will fix exactly that bug in the exercises.

Block statements

STEP THROUGH

A block statement is a group of statements wrapped in braces. You will see blocks after if, for, functions, and more. The braces are not themselves a pause or a value; they group the statements between them, which still run in order.

Real-life analogyA block is a paragraph

If statements are sentences, a block is a paragraph: several related instructions bundled together. The paragraph analogy is useful because it reminds you that a block is still one statement from the outside.

In real life: A paragraph groups related sentences
In JavaScript: A block groups related statements
In real life: Sentences still read in order
In JavaScript: Statements inside still run top to bottom
In real life: A paragraph can be moved as one unit
In JavaScript: A block can be the body of if, for, or a function

Where the analogy stops: Paragraphs do not create variable scope. JavaScript blocks do for let and const, which later lessons explore more deeply.

Step through a block statement
Step 0 of 4Ready
Your turn: follow the blue line

A block statement groups statements and runs them in order. Step through the paragraph of code.

Running in
  1. script
Next: line 2
Click the blue line to take the next stepPop out in the code editor (opens in a new tab)JavaScript
{  const message = "inside";  console.log(message);}console.log("after block");
CallStoreChangeResultRun = next line. Ran = already executed.
Recent returnsNothing yet. Start with the blue line.
A guided replay recorded from real JavaScript calls, not an engine debugger. Step follows executed statements; Back reviews a snapshot. Reset starts a fresh run.

Notice that const message is inside the block. With let and const, names belong to the block that creates them. You do not need the full scope rules yet; just remember that braces often make a small room for names.

When { starts a block, not an object

INTERACTIVE

Braces are overloaded. They can start a block statement, or they can be part of an object literal expression. Context decides. At the start of a statement in a real script, { a: 1 } starts a block. Inside that block, a: is a label, and 1 is an expression statement. The script completion value is 1.

When do braces mean object?
Script snippetsJavaScript
{ a: 1 }({ a: 1 })(() => { a: 1 })()(() => ({ a: 1 }))()
Line 1 resultblock completion: 1
1
Step 1 of 4Choose a line

At statement start, braces begin a block. The label a: points at expression 1, so a script completion can be 1.

These results are from real JavaScript script parsing. Chrome DevTools may treat { a: 1 } typed alone as an object for convenience.
Console convenience is not script grammar

Chrome DevTools and some other browser consoles try to be helpful: when you type { a: 1 } alone, they may treat it as an object expression. A real script parses the same text at statement start as a block. Use ({ a: 1 }) when you mean an object expression.

Arrow functions have the same issue. () => { a: 1 } has a block body and returns undefined. To return an object immediately, wrap the object in parentheses: () => ({ a: 1 }).

Semicolons and automatic insertion

STEP THROUGH

Semicolons mark statement endings. JavaScript also has automatic semicolon insertion, or ASI, which can add missing semicolons at certain line breaks. ASI is like autocorrect for periods: usually helpful, occasionally wrong for what you meant.

Real-life analogySemicolons are periods; ASI is autocorrect

If you forget a period in a text message, autocorrect may add one. Usually that helps. Sometimes it changes the meaning. ASI is the code version: it follows rules, not your intention.

In real life: A period ends a sentence
In JavaScript: A semicolon ends many statements
In real life: Autocorrect guesses missing punctuation
In JavaScript: ASI inserts semicolons in allowed places
In real life: Autocorrect can guess wrong
In JavaScript: ASI can join a line starting with [ or end return early

Where the analogy stops: Semicolons are not required after every JavaScript construct. Blocks after if and function declarations do not need them. The analogy is about statement endings, not all punctuation.

First pitfall: a line that begins with [, (, or a template backtick can continue the previous statement. Toggle the semicolon below. In Chrome and Node, the broken version throws TypeError: Cannot read properties of undefined (reading 'forEach'). Other engines may word the message differently, so tests assert the error name and treat the V8 message as an example.

Toggle the semicolon before a line that starts with [
Step 0 of 2Ready
Your turn: follow the blue line

Toggle the semicolon on line 1. Predict whether line 2 starts fresh or gets glued to line 1.

Running in
  1. script
Next: line 1
Click the blue line to take the next stepPop out in the code editor (opens in a new tab)JavaScript
[1, 2].forEach((n) => console.log(n));
CallStoreChangeResultRun = next line. Ran = already executed.
Recent returnsNothing yet. Start with the blue line.
Line 1 ending

Changing the option starts a fresh recorded run.

A guided replay recorded from real JavaScript calls, not an engine debugger. Step follows executed statements; Back reviews a snapshot. Reset starts a fresh run.

Second pitfall: return followed by a line break. The displayed function below really returns undefined, because ASI ends the return statement before the object-looking block.

The return-newline pitfall
Function sourcePop out in the code editor (opens in a new tab)JavaScript
function makeCard() {  return  {    title: "JavaScript"  };}console.log(makeCard());
Outputreal result
undefined

Put the object on the same line as return, or wrap the expression intentionally.

Try it yourself

The displayed function returns undefined. ASI inserts a semicolon immediately after return, before the object-looking block.

The source shown here is the shape of the real function the test verifies.
Practical beginner rule

Write semicolons at statement ends while you are learning. Never put the value for return on the next line. If a line starts with (, [, or a template backtick, make sure the previous statement has clearly ended.

Comments, whitespace, and formatting

Comments are sticky notes for humans. JavaScript removes them before running the code. Use comments to explain why something is done, or to leave a short note for future maintainers. Do not use a comment to repeat code that is already obvious.

Real-life analogyComments are sticky notes

A useful comment helps a person understand intent. It does not make the computer do anything new.

In real life: A sticky note on a recipe says “double this for guests”
In JavaScript: A comment says why a line exists
In real life: The oven ignores the sticky note
In JavaScript: JavaScript ignores comments at runtime
In real life: Too many notes become clutter
In JavaScript: Too many obvious comments make code harder to read

Where the analogy stops: Comments can be read by tools, especially JSDoc-style comments. They are ignored by the JavaScript runtime, but not always by editors or documentation generators.

Comment formsPop out in the code editor (opens in a new tab)JavaScript
// Explain why this line exists.const page = "https://completefrontend.com";/* A block comment can   span several lines. *//** JSDoc-style comments describe functions for tools. */const text = "// this is text, not a comment";
  • // starts a single-line comment.
  • /* ... */ is a block comment. It can span lines, but it does not nest.
  • /** ... */ is JSDoc-style: still a block comment, but tools can use it.
  • // inside quotes is part of a string, not a comment.

Whitespace is like spacing in a sentence. Spaces, tabs, and most line breaks help readers but do not change meaning: 2+2 and 2 + 2 are the same expression. Formatting tools such as Prettier keep spacing consistent. The exceptions you have met are line breaks near return and before lines that can attach to the previous statement.

Where you'll use this

This topic appears everywhere. Function bodies are statement lists. Conditions are expressions. if, loops, and functions use blocks. Comments explain non-obvious decisions. Semicolons and formatting make reviews calmer because readers do not have to guess where a statement ends.

Everyday structurePop out in the code editor (opens in a new tab)JavaScript
// Keep related steps together.if (message.trim() !== "") {  const loud = message.toUpperCase();  console.log(loud);} // Start lines with [ safely after a statement.const count = 1;["ready"].forEach((word) => console.log(word));

Line 2 uses an expression as the condition. Lines 2 through 5 are a block. Line 8 adds a semicolon before a line that starts with [. The comments explain intent, not the obvious fact that console.log prints.

Up next, strict mode begins with "use strict";. That line is a directive: a special expression statement at the top of a script or function. You do not need the full strict-mode rules yet; just notice that the structure matters.

Common misconceptions

“Expressions are only math.”

Strings, comparisons, property reads, and function calls are expressions too because they produce values.

“Semicolons are always optional.”

ASI often helps, but missing semicolons before [, (, or a template backtick can join lines in surprising ways.

“Braces always mean object.”

At statement start, braces begin a block. Use parentheses when you need an object expression.

“Indentation creates blocks.”

JavaScript uses braces, not indentation, to group statements. Indentation is for humans.

“Comments can be nested if they look balanced.”

Block comments end at the first */. Nested /* ... */ comments break.

Lookalikes that cause bugs
Looks likeActuallySafe habit
{ a: 1 }A block with a label at statement startWrite ({ a: 1 }) for an object expression
return then newline then objectReturn undefined, then unreachable blockKeep the return value on the same line
if (ready); { ... }if controls the empty statementDelete the stray semicolon
// inside a stringOrdinary textOnly // outside strings starts a comment

Practice: read the structure

6 EXERCISES
Exercise 1 · Warm-upClassify two pieces

Which one is an expression: if (x) {} or x > 2?

Answer, then press Check. Spacing and letter case don’t matter.

    Exercise 2 · PracticePredict return + newline

    Predict exactly what the program prints.

    Starter codePop out in the code editor (opens in a new tab)JavaScript
    function label() {
      return
      {
        text: "done"
      };
    }
    console.log(label());

    Answer, then press Check. Spacing and letter case don’t matter.

      Exercise 3 · PracticeFix the missing-semicolon bug

      The broken version throws in V8. Add one character so it prints the array items.

      Starter codePop out in the code editor (opens in a new tab)JavaScript
      const a = 1
      [1, 2].forEach((n) => console.log(n));

      Answer, then press Check. Spacing and letter case don’t matter.

        Exercise 4 · PracticeFind the stray semicolon

        Which character makes this program log even when isReady is false?

        Starter codePop out in the code editor (opens in a new tab)JavaScript
        let isReady = false;
        if (isReady);
        {
          console.log("Running anyway");
        }

        Answer, then press Check. Spacing and letter case don’t matter.

          Exercise 5 · PracticeTurn a block into an object

          What should wrap { a: 1 } so JavaScript treats it as an object expression?

          Answer, then press Check. Spacing and letter case don’t matter.

            Exercise 6 · ChallengeWrite helpful comments

            Pick a small piece of your own code and add one comment that explains why it exists. Avoid repeating the code in English.

              Quiz: check your understanding

              8 QUESTIONS

              Answer before expanding explanations. Every code answer is based on real JavaScript behavior.

              Lesson quiz · 8 questionsScore: first tries count
              1. Question 1 of 8Which description best matches an expression?

                Choose an answer to see the explanation.

              2. Question 2 of 8What does this print?

                Read the code, then predictPop out in the code editor (opens in a new tab)JavaScript
                let score = 2 + 3;
                console.log(score);

                Choose an answer to see the explanation.

              3. Question 3 of 8What is ; by itself?

                Choose an answer to see the explanation.

              4. Question 4 of 8What does this program print?

                Read the code, then predictPop out in the code editor (opens in a new tab)JavaScript
                let ok = false;
                if (ok);
                {
                  console.log("surprise");
                }

                Choose an answer to see the explanation.

              5. Question 5 of 8In a real script, what is { a: 1 } at the start of a statement?

                Choose an answer to see the explanation.

              6. Question 6 of 8What does the return-newline function print?

                Read the code, then predictPop out in the code editor (opens in a new tab)JavaScript
                function makeCard() {
                  return
                  {
                    title: "JavaScript"
                  };
                }
                console.log(makeCard());

                Choose an answer to see the explanation.

              7. Question 7 of 8Which comment form can span more than one line?

                Choose an answer to see the explanation.

              8. Question 8 of 8Which whitespace choice can change meaning?

                Choose an answer to see the explanation.

              Key takeaways

              • Statements are complete instructions; expressions produce values.
              • Expression statements are useful when an expression has a side effect, like console.log.
              • A block statement groups statements and creates block scope for let and const.
              • At statement start, braces start a block. Use parentheses for object expressions when needed.
              • ASI helps, but be careful after return and before lines starting with (, [, or a template backtick.
              • Comments are for humans; whitespace mostly helps readers, and formatting tools keep it consistent.

              Remember the one-liner.
              JavaScript reads a script as statements; expressions provide values inside them; punctuation and formatting tell readers and the parser where each idea ends.

              If you want to revisit the big picture, return to Why JavaScript?. Up next: Strict mode.

              CompleteFrontend Clear concepts. Working examples.