Syntax#

JavaScript is a C-family grammar with curly braces, semicolons (optional thanks to ASI but written by convention), and expression-rich syntax. Source is UTF-16 internally; UTF-8 on disk is universal. "use strict" (implicit inside modules and classes) tightens the rules around globals and silent failures.

/types`. For the operators that combine them, see Operators.

function greet(name) {
  console.log(`hello, ${name}`);
}

greet("operator");

Comments#

Line comments start with //; block comments wrap with /* ... */ and do not nest. Doc comments (/** ... */) are read by JSDoc, TypeScript, and most editors.

// single-line comment

/*
 * block comment
 */

/**
 * @param {string} name
 * @returns {string}
 */
function greet(name) { return `hello, ${name}`; }

Identifiers#

Identifiers are Unicode letters, digits, _, and $; they cannot start with a digit. Convention is camelCase for variables and functions, PascalCase for classes and constructors, UPPER_SNAKE for module-level constants, and #name for private class fields.

let userCount = 0;             // local
const MAX_RETRIES = 5;         // module-level constant
class HttpClient {}            // class
class Cache { #data = new Map(); }   // private field

Keywords#

Reserved words the operator cannot use as identifiers.

await break case catch class const continue debugger default
delete do else enum export extends false finally for function
if import in instanceof new null return super switch this
throw true try typeof undefined var void while with yield
let static implements interface package private protected
public async of as from get set target

Literals#

Every primitive has a literal form.

const n   = 42;                // number
const big = 1_000_000;         // underscore separators
const x   = 0xff;              // hex
const o   = 0o755;             // octal
const b   = 0b1010_0001;       // binary
const pi  = 3.14159;           // float
const z   = 9007199254740993n; // bigint

const s   = "hello";           // string
const t   = `hello, ${name}`;  // template literal
const m   = `multi
line`;                         // template literals span lines

const arr = [1, 2, 3];         // array literal
const obj = {name: "rk"};      // object literal
const re  = /^[a-z]+$/i;       // regex literal

const f   = false;
const u   = undefined;
const z2  = null;

Statements#

A statement does something. Assignment, return, throw, function and class declarations, if / for / while / switch blocks, import / export.

const x = 1 + 2;               // declaration statement
import fs from "node:fs";      // import statement
if (x > 0) process(x);         // compound statement
for (let i = 0; i < 3; i++) {  // compound statement
  step(i);
}
return x;                      // return statement

Semicolons separate statements. ASI (automatic semicolon insertion) inserts them at line breaks in most cases, but two forms still bite: a leading (, [, / on a new line that chains onto the previous expression. Write explicit ; to dodge both.

Expressions#

An expression evaluates to a value. Arithmetic, function calls, ternary, arrow bodies, optional chaining, and template literals are all expressions.

1 + 2                          // arithmetic
xs.length > 0                  // relational
xs.reduce((a, b) => a + b, 0)  // method call + arrow
x > 0 ? x : -x                 // ternary
user?.profile?.name            // optional chaining
`${name}=${value}`             // template literal

The right-hand side of an assignment, the test in an if, and function arguments all consume expressions. An expression statement is a bare expression used as a statement (console.log("hi"), await fetch(url)).

References#