Syntax, Values and Statements

Syntax is the grammar of the language: which texts count as valid programs. This lesson covers the atoms — values, literals, comments — and the two kinds of sentence you will write: statements (do this) and expressions (compute this). It also settles semicolons for good.

What syntax is

Source code is text with strict rules

A JavaScript file is plain text. The engine reads it as a stream of tokens — words, numbers, operators — and assembles them into instructions. Syntax is the rulebook for which token sequences are valid. When the rulebook is violated you get a SyntaxError and nothing in the file runs — not even the lines before the mistake, because the engine reads the whole file before executing any of it.

console.log("first");   // this line is fine, but...
console.log("second     // ...the unclosed quote makes the
                        // WHOLE file a SyntaxError

You should see something like:

Uncaught SyntaxError: Invalid or unexpected token

Read the line number, and look one line up as well — the engine often reports the line after the actual mistake. Most bugs at this stage are syntax bugs, and they are the cheapest to fix.

Values and literals

A value is a piece of data

Everything a program ever handles is a value: the number of clicks, a user's name, a list of products. A literal is a value written directly in the source — you can spot literals by their shape:

42            // number — every number, integer or decimal
3.14          // also a number (there is no separate integer type)
"text"        // string — text in quotes
`text`        // template literal: quotes that can hold variables (lesson 06)
true, false   // boolean — the two answers to every yes/no question
null          // "deliberately empty" — set by the programmer
undefined     // "never filled in" — set by the engine

Comments explain why

// starts a comment to the end of the line; /* ... */ spans several lines; the engine skips both. A good comment records why the code exists or a non-obvious constraint — // add 1 teaches nobody anything.

Statements and expressions

A statement is an instruction

A statement is one complete instruction: "declare this", "log that", "if this then that". Statements are the sentences of the language; the engine executes them in order.

An expression produces a value

An expression is any code that produces a value: 2 + 3, "page " + count, user.name, even a bare 42. Expressions appear inside statements, wherever a value is expected:

// statement:      const total  =   2 + 3;
//                 (keyword)    (name)  (expression)
const total = 2 + 3;

// statement: console.log( expression )
console.log(total * 2); // the expression total * 2 becomes 10

The distinction pays off immediately: anywhere the language wants a value, you may put an arbitrarily rich expression; where it wants a statement, an expression alone is not enough.

Semicolons and ASI

The rule you should follow

Semicolons separate statements, and the engine can usually infer where they belong — the mechanism is called automatic semicolon insertion (ASI). The community rule is simple: end every statement with a semicolon and let tooling confirm it. You still need to know the rule the engine applies, because you will read other people's code.

The rule the engine applies

ASI inserts a semicolon when the next line cannot continue the current one. Two consequences, both famous traps:

// TRAP 1: a line starting with ( or [ joins the previous line.
const name = "Ada";
const say = "Hi"        // ASI inserts nothing: this line CONTINUES below...
(say);                  // ...it becomes "Hi"(say) → TypeError at runtime

// TRAP 2: return refuses to be split across lines.
function distance() {
  return          // ASI ends the statement HERE
    10;           // unreachable — the function returns undefined
}

You should see for trap 2: the function returns undefined, not 10 — a silent bug, with no error at all. Keep return and its value on one line, and never let a line start with ( or [.

Strict mode

What "use strict" does

JavaScript was designed in 1995 with defaults that are forgiving to a fault. Strict mode is a switch that turns forgiving behaviour into loud errors. Enable it with one string at the top of a file:

"use strict";

score = 10; // oops — no const/let. Without strict: a silent global variable.
            // With strict mode:

You should see:

Uncaught ReferenceError: score is not defined

Loud errors while learning are a gift: they surface at the mistake, not three screens later. And from lesson 02 you know that type="module" scripts and class bodies are always strict — modern code is strict by default; write it that way by hand too.

Naming things

Identifier rules

Names (identifiers) may contain letters, digits, _ and $, and must not start with a digit. JavaScript is case-sensitive: userName, username and USERNAME are three different names — the source of many quiet undefineds.

The convention: camelCase

const firstName = "Ada";  // variables and functions: camelCase
const MAX_RETRIES = 3;    // fixed constants: UPPER_SNAKE_CASE
// first_name and FirstName also WORK — but a codebase picks ONE style and keeps it.

Practice: predict, then run

The task

In the console (lesson 01), type each snippet and write your prediction before pressing Enter. Then run demo foundations/09_values_and_types.js with node and check every prediction:

console.log(typeof 42, typeof "42", typeof true);
console.log(10 / 2, 10 / 4);
console.log("ten" + 10);

The checklist

  • You can point at a statement and at an expression in code you did not write.
  • You can explain why an unclosed quote kills the whole file, while a wrong value does not.
  • You know the two ASI traps and the one-line habits that avoid both.
  • You can say exactly what strict mode changed in the score = 10 example.