completefrontend
Open lab My progress
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 a statement (a complete instruction) from an expression (code that makes a value).
  • 02
    Group code safelyUse braces to make blocks, and know when braces make an object instead.
  • 03
    Avoid line-break mistakesUse semicolons, comments, and spacing on purpose, and spot the line breaks that change what code does.

How JavaScript reads your code

A JavaScript file is a list of instructions. JavaScript reads them from top to bottom, one after another. In an earlier lesson, you saw that a program is like a recipe: a list of steps done in order. This lesson is about how each step is written. You will learn about:

  • Statements: complete instructions, like one step of a recipe.
  • Expressions: smaller pieces inside a statement that make a value.
  • Braces, { }, which group several steps together.
  • Semicolons, ;, which mark where a step ends.
  • Comments and spacing, which help people read the code.

First you will see tiny programs. Then you will see four common mistakes:

  • return with its value on the next line.
  • A missing semicolon before a line that starts with [.
  • An extra semicolon right after if (...).
  • Braces that look like an object but are not one.
Real-life analogyStatements are sentences; expressions are phrases

A statement is like a complete sentence. It tells JavaScript to do one thing. An expression is like a phrase, a few words that are not a full sentence. It makes a value. That value can then be used inside a statement. For example, the phrase 2 + 3 makes the value 5. The statement let score = 2 + 3; keeps that value under the name score.

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
The main idea

A statement is a complete instruction. An expression is a piece of code that makes a value. A statement can hold expressions inside it. An expression can also stand alone as a statement. You do that when the expression does something useful, like printing with console.log.

Statements vs expressions

INTERACTIVE

To tell them apart, ask one question:

  • For an expression, ask: what value does this make?
  • For a statement, ask: what instruction does this give?

One line can have both. In let x = 5 + 3;, the whole line is a statement. It is a declaration: a statement that makes a new name, here x. The part 5 + 3 is an expression inside it.

A value inside a statementPop out in the code editor (opens in a new tab)JavaScript
const teaPrice = 3;const total = teaPrice + 2;console.log(total);

Line 1 makes teaPrice and gives it the value 3. Line 2 is another declaration. First the expression teaPrice + 2 makes 5. Then the statement stores 5 in total. Line 3 calls console.log, which prints 5.

The whole line const total = teaPrice + 2; is a statement. Inside it, the expression teaPrice + 2 makes the value 5. The statement then puts 5 in a box called total.the whole line is a statementconst total = teaPrice + 2;teaPrice + 2expression5its value5totalstored in total
The whole line is one statement: one complete instruction. The part teaPrice + 2 is an expression. It makes a value, 5. Then the statement puts that value in total.
Give an existing name a new valuePop out in the code editor (opens in a new tab)JavaScript
let cartTotal = 0;
cartTotal = 3 + 2;
console.log(cartTotal);

Line 1 starts cartTotal at 0. Line 2 is an assignment: a statement that gives a name a new value with =. The right side, 3 + 2, is an expression. It makes 5, and 5 replaces the old value. Line 3 prints 5.

A function call gives back a valuePop out in the code editor (opens in a new tab)JavaScript
const drink = "tea";
const label = drink.toUpperCase();
console.log(label);

Line 2 calls toUpperCase(), which turns text into capital letters. The call is an expression, because it makes a value: "TEA". Line 3 prints that value. So a call does not only do things, like printing. It can also give back a value.

The table below sums up four kinds of code. Read each row as: "to spot this kind of code, ask this question."

Four kinds of code and how to spot each one
Kind of codeQuestion to askTiny exampleWhat JavaScript does with it
ExpressionWhat value does this make?2 + 2It works out the value 4.
StatementWhat instruction does this give?let total = 4;It does one complete step of the program.
BlockWhich statements are grouped in braces?{ console.log(total); }It runs the grouped statements in order.
CommentWhat note helps people?// explain whyNothing. It skips the comment.

Now sort these cards. Look closely at console.log("hi");. The call is an expression, but we write it as a whole line because we want it to print. Doing something besides making a value, like printing, is called a side effect.

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

Put each card in its group. If a whole line is just an expression that we write so it does something, like printing, choose Expression used as statement.

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

Later lessons use these words a lot:

  • The condition of an if, inside its round brackets, is an expression.
  • The code that an if runs is a statement.
  • The line "use strict"; in the next lesson is an expression used as a statement. It has a special name: a directive.

Expressions as whole lines, and the empty statement

STEP THROUGH

Some expressions can stand alone as a whole line. Then they count as a statement. A few examples:

  • score; is allowed, but it is almost never useful. It only reads the value and does nothing with it.
  • console.log(score); is useful, because the call prints something.
  • A semicolon on its own, ;, is allowed too. It is the empty statement: a complete instruction that does nothing on purpose.
Step through statements and expressions
Step 0 of 4Ready
Your turn: follow the blue line

A statement is a complete instruction. An expression is a piece of code that makes a value, often inside a statement.

Running in
  1. script
Next: line 1
score;console.log("score:", score);;
CallStoreChangeResultBlue line: runs next. 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 shows a completion value for each line. That is the result JavaScript notes down after it runs a statement. You don't see it in a normal program. Some tools show it, like the browser console and Node's vm.runInContext. A completion value is not printed output. console.log prints text on the screen, but its own value is undefined.

A lone semicolon can cause a bug

; on its own does nothing. That sounds harmless. But look at if (isReady);. Now the if controls only the empty statement. The block after it is not part of the if, so it runs every time. You will fix this exact bug in the exercises.

Blocks: braces that group statements

STEP THROUGH

A block statement, or block, is a group of statements inside braces, { }. You will see blocks after if, after for, in functions, and in many other places. The braces only group the statements. They don't make a value, and they don't pause anything. The statements inside still run in order, from top to bottom.

Real-life analogyA block is a paragraph

If statements are sentences, a block is a paragraph. It holds several sentences that belong together. From the outside, a paragraph is one piece of the page. In the same way, a block counts as one statement.

In real life: A paragraph groups sentences that belong together
In JavaScript: A block groups statements that belong together
In real life: You still read the sentences in order
In JavaScript: The statements inside still run from top to bottom
In real life: You can move a paragraph as one piece
In JavaScript: A block can be the code an if, a for, or a function runs
Step through a block
Step 0 of 4Ready
Your turn: follow the blue line

A block groups statements and runs them in order. Step through it line by line.

Running in
  1. script
Next: line 2
{  const message = "inside";  console.log(message);}console.log("after block");
CallStoreChangeResultBlue line: runs next. 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.

Look at const message. It is made inside the block. A name made with let or const inside braces belongs to that block. Code outside the braces can't use it. You will learn the full rules later, in the lessons on scope. For now, remember: braces often make a small room for names.

An if runs a block only when its condition is truePop out in the code editor (opens in a new tab)JavaScript
const hasItems = true;
if (hasItems) {
  console.log("Show checkout");
}
console.log("Page ready");

Line 2 checks hasItems. It is a boolean: a value that is either true or false. Here it is true, so line 3 runs and prints Show checkout. The block ends on line 4. Then line 5 prints Page ready. If hasItems were false, JavaScript would skip only the block. Line 5 would still print Page ready.

A name stays inside its blockPop out in the code editor (opens in a new tab)JavaScript
{  const drink = "tea";  console.log(drink);}console.log(typeof drink);

Line 2 makes drink inside the braces. Line 3 prints tea. Line 5 is outside the block. It uses typeof, which tells you the type of a value as text. typeof is safe to use on a name that doesn't exist: it gives "undefined" instead of an error. So line 5 prints undefined. That shows drink can't be used outside its block.

When { starts a block, not an object

INTERACTIVE

Braces have two jobs in JavaScript:

  • They can start a block, as you just saw.
  • They can make an object: a value that holds named things, like { name: "Asha" }.

Where the braces are decides the job. At the start of a statement, { a: 1 } starts a block, not an object. Inside that block, a: is a label: a name with a colon, put in front of a statement. Labels are rare; you only need to know they exist. The 1 after the label is an expression used as a statement. So the completion value of the whole line is 1.

Left: { a: 1 } at the start of a line is a block, so no object is made. Right: ({ a: 1 }) inside round brackets makes an object that holds a: 1.start of a line{ a: 1 }a blockno object is madeinside round brackets({ a: 1 })a: 1object
The same braces, two jobs. At the start of a line, { a: 1 } is a block, so no object is made. Inside round brackets, JavaScript expects a value, so ({ a: 1 }) makes an object.
When do braces make an object?
Four lines that use bracesJavaScript
{ a: 1 };({ a: 1 });(() => { a: 1 })();(() => ({ a: 1 }))();
Line 1 resulta block: the result is 1
1
Step 1 of 4Choose a line

At the start of a statement, braces start a block. Inside it, a: is a label and 1 is a statement, so the result is 1.

Each line runs on its own, as a script. The result shown is its completion value, the result JavaScript notes down. It is not printed output. Chrome DevTools may show { a: 1 } typed on its own as an object, to be helpful.
Braces after = make an objectPop out in the code editor (opens in a new tab)JavaScript
const user = { name: "Asha" };
console.log(user.name);

Here the braces come after =. After =, JavaScript expects a value, so the braces make an object. No round brackets are needed. Line 2 reads the object's name and prints Asha. You only need round brackets when an object is at the very start of a statement.

The browser console reads braces differently

Chrome DevTools and some other browser consoles try to help you. If you type { a: 1 } on its own there, they may show it as an object. A real script reads the same text, at the start of a statement, as a block. Write ({ a: 1 }) when you mean an object.

Arrow functions have the same problem. An arrow function is a short way to write a function, like () => 5. In () => { a: 1 }, the braces after => are the function's block. There is no return, so it gives back undefined. To give back an object, wrap it in round brackets: () => ({ a: 1 }).

Semicolons, and when JavaScript adds them for you

STEP THROUGH

A semicolon, ;, marks the end of a statement. If you leave one out, JavaScript can sometimes add it for you at a line break. This is called automatic semicolon insertion, or ASI for short. ASI is like autocorrect on your phone. It usually helps, but sometimes it guesses wrong.

Real-life analogySemicolons are periods; ASI is autocorrect

You forget a period in a text message, and autocorrect adds one. Usually that helps. Sometimes it changes what you meant. ASI does the same for code. It follows fixed rules. It can't know what you meant.

In real life: A period ends a sentence
In JavaScript: A semicolon ends a statement
In real life: Autocorrect adds a missing period
In JavaScript: ASI adds a missing semicolon at some line breaks
In real life: Autocorrect can guess wrong
In JavaScript: ASI can join two lines into one, or end return too early

First mistake: some lines can join onto the line before them. This happens when a line starts with [, (, or a backtick (`, used for template strings). JavaScript then reads the two lines as one statement. Switch the semicolon on and off below. In Chrome and Node, the version without it throws this error: TypeError: Cannot read properties of undefined (reading 'forEach'). Other browsers may word the message differently. The error type, TypeError, is the same.

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

Switch the semicolon at the end of line 1 on or off. Guess first: does line 2 start a new statement, or join onto line 1?

Running in
  1. script
Next: line 1
[1, 2].forEach((n) => console.log(n));
CallStoreChangeResultBlue line: runs next. Ran: already executed.
Recent returnsNothing yet. Start with the blue line.
The end of line 1

Each time you change the choice, the code runs again from the start.

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 mistake: a line break right after return. The function below really gives back undefined. ASI adds a semicolon right after return, so the function stops there. The object on the next lines is never returned.

A line break after return
The value starts on the next linePop out in the code editor (opens in a new tab)JavaScript
function makeCard() {  return  {    title: "JavaScript"  };}console.log(makeCard());
Outputwhat it prints
undefined

To fix it, put the object on the same line as return.

Try it yourself

This function gives back undefined. ASI adds a semicolon right after return, so the object on the next lines is never returned.

The code shown here is the same as the real function that the lesson's tests run.
Left: return, then the object on the next line. JavaScript adds a semicolon right after return, so the function returns undefined. Right: return and the object on the same line, so the function returns the object.value on the next linemakeCard()return;added by JavaScript{ title: … }returns undefinedvalue on the same linemakeCard()return { title: … };returns the object
On the left, the object starts on the next line. JavaScript adds a ; right after return, so the function stops there and gives back undefined. On the right, the object is on the same line, so it is returned.
Return the object on the same linePop out in the code editor (opens in a new tab)JavaScript
function makeCard() {  return { title: "JavaScript" };}console.log(makeCard().title);

Line 2 keeps return and the object on the same line. So the function gives back the object, and line 4 prints its title: JavaScript. This is the normal way to return an object from a function.

Safe habits for semicolons

While you are learning, end every statement with a semicolon. Never put the value of return on the next line. If a line starts with (, [, or a backtick, make sure the line before it ends with a semicolon.

Comments, spacing, and formatting

A comment is a note in your code for people. JavaScript skips comments; they never run. Use a comment to say why the code does something. It can also be a short note for whoever reads the code later. Don't use a comment to repeat what the code already says.

Real-life analogyComments are sticky notes

A good note helps a person understand what you wanted to do. It doesn't 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 is there
In real life: The oven doesn't read the sticky note
In JavaScript: JavaScript skips comments when it runs the code
In real life: Too many notes make the recipe hard to read
In JavaScript: Too many obvious comments make code harder to read
The kinds of commentsPop 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";console.log(page);

Line by line:

  • Line 1 is a one-line comment.
  • Lines 3 and 4 are one block comment, across two lines.
  • Line 5 is a JSDoc comment, explained below.
  • Line 6 is code. It stores text that happens to contain //.
  • Line 7 prints page, so the output is https://completefrontend.com. The comments don't change it.

The rules for each kind of comment:

  • // starts a one-line comment. It ends at the end of the line.
  • /* ... */ is a block comment. It can cover several lines. You can't put one block comment inside another.
  • /** ... */ is a JSDoc comment. It is still a block comment, but code editors read it to show help about a function.
  • // inside quote marks is part of the text, not a comment.
Left: your code has a comment line and a code line. Right: what runs has only the code line, because JavaScript skips the comment.your code// a note for peopleconst total = 5;note and codewhat runsconst total = 5;only the code
A comment is a note for people. JavaScript skips it before the code runs. So the comment never changes what your program does.
A comment that says whyPop out in the code editor (opens in a new tab)JavaScript
// Show the greeting only after the user signs in.
const signedIn = true;
if (signedIn) {
  console.log("Welcome, Asha");
}

The comment on line 1 gives a reason. It doesn't describe the code on the next line. JavaScript skips line 1. It sees that signedIn is true, and prints Welcome, Asha. Avoid comments like // set signedIn to true. The code already says that.

Whitespace means spaces, tabs, and line breaks. It works like the spaces between words. Most whitespace helps people read, but it doesn't change what the code means. For example, 2+2 and 2 + 2 are the same expression. Tools called formatters, like Prettier, fix the spacing for you so it looks the same everywhere. You have already seen the two exceptions: a line break right after return, and a line break before a line that can join the line above.

Spacing that changes nothingPop out in the code editor (opens in a new tab)JavaScript
const price=3;const total = price + 2;console.log(total);

Line 1 has no spaces around =. Line 2 has spaces around = and +. Both lines work, and line 3 prints 5. Write it the second way. JavaScript gets the same values either way, but people find spaced code easier to read.

Where you'll use this

You will use these ideas in almost every program:

  • The code inside a function is a list of statements.
  • Conditions are expressions.
  • if, loops, and functions use blocks.
  • Comments explain choices that are not obvious.
  • Semicolons and neat spacing show readers where each statement ends, so nobody has to guess.
Comments, a block, and semicolons togetherPop 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 of the if. The braces from line 2 to line 5 make a block. Line 8 ends with a semicolon, so line 9, which starts with [, is a new statement. The comments on lines 1 and 7 explain the reason for the code. They don't say the obvious, like "console.log prints".

Prepare a small form messagePop out in the code editor (opens in a new tab)JavaScript
const message = "  hello  ";
const cleanMessage = message.trim();
if (cleanMessage !== "") {
  console.log(cleanMessage.toUpperCase());
}

Text typed into a form often has extra spaces. Line 2 uses trim(), which removes spaces from both ends. It gives "hello". Line 3 checks that this text is not empty, so line 4 prints HELLO. This way, an empty form field never sends an empty message.

The next lesson, Strict mode, starts with the line "use strict";. That line is a directive: an expression used as a statement, at the top of a script or function, that turns on a special mode. You don't need the strict-mode rules yet. Just notice that you can now read how the line is built.

Common misconceptions

“Expressions are only math.”

Text, comparisons, reading a property, and function calls are expressions too. They all make a value.

“Semicolons are always optional.”

ASI often adds them for you. But without a semicolon, a line that starts with [, (, or a backtick can join the line before it.

“Braces always make an object.”

At the start of a statement, braces start a block. Wrap them in round brackets when you want an object.

“Indenting code makes a block.”

Braces make a block. Indenting, the space at the start of a line, only helps people read.

“A block comment can go inside another one.”

A block comment ends at the first */. If you put one /* ... */ inside another, the outer one ends too early.

The table below lists code that looks like one thing but is another. Read each row as: "this looks like X, but it really is Y, so do Z."

Code that looks like one thing but is another
When you seeWhat it really isWhat to do instead
{ a: 1 } at the start of a statementA block with a label inside, not an object.Write ({ a: 1 }) when you want an object.
return, a line break, then an objectThe function returns undefined. The code below return never runs.Keep the value on the same line as return.
if (ready); { ... }The if controls only the empty statement ;. The block always runs.Delete the semicolon after if (ready).
// inside quote marksPlain text, not a comment.Remember: only // outside quote marks starts a comment.

Practice: read the structure

6 EXERCISES

Six exercises, from easy to harder. Try each one before you open the hints.

Exercise 1 · Warm-upFind the expression

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, then a line break

    What exactly does this program print?

    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

      In Chrome and Node, this code throws an error. Add one character so it prints the two numbers in the list. What does it print then?

      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 extra semicolon

        This program prints its message even though isReady is false. Which character causes that?

        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 you wrap around { a: 1 } so JavaScript makes an object?

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

            Exercise 6 · ChallengeWrite a helpful comment

            Pick a small piece of your own code. Add one comment that says why it is there. Don't just repeat the code in English.

              Quiz: check your understanding

              8 QUESTIONS

              Answer each question before you open its explanation. For code questions, run the code in your head one statement at a time. Every answer was checked by running real JavaScript.

              Lesson quiz · 8 questionsScore: first tries count
              1. Question 1 of 8Which sentence best describes 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 ; on its own?

                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 8This function has a line break right after return. What does it 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 kind of comment can cover more than one line?

                Choose an answer to see the explanation.

              8. Question 8 of 8Which spacing choice can change what the code does?

                Choose an answer to see the explanation.

              Key takeaways

              • A statement is a complete instruction. An expression makes a value.
              • An expression can be a whole line. That is useful when it does something, like console.log printing.
              • A block is a group of statements in braces. Names made with let or const inside it stay inside it.
              • At the start of a statement, braces make a block. Wrap them in round brackets when you want an object.
              • ASI adds some missing semicolons. Watch out after return, and before lines that start with (, [, or a backtick.
              • Comments are for people. Spacing is mostly for people too, and formatters keep it neat.

              Remember the one-liner.
              Code is a list of statements. Expressions make the values inside them. Semicolons and braces show where each one ends.

              To look at the big picture again, go back to Why JavaScript?. Coming next: Strict mode.

              CompleteFrontend Clear concepts. Working examples.