1 · Variables & Declarations

JavaScript offers three keywords for declaring variables: var, let, and const. Note: prefer let and const in modern code for block scoping and immutability.

// ES2015 + variable declarations
var legacy = 'function‑scope';   // avoid in new code
let mutable = 'block‑scope';
const IMMUTABLE = 42;       // cannot be reassigned

2 · Primitive & Reference Data Types

Primitives: string, number, bigint, boolean, null, undefined, and symbol. Objects (including functions and arrays) are reference types. Note: typeof null === "object" is an historical quirk.

// Type checks
typeof "hi"          // "string"
typeof 123n          // "bigint"
typeof function(){}  // "function" (subtype of object)
typeof null          // "object" (bug preserved for legacy)

3 · Operators (+ – * / …)

JavaScript supports arithmetic, assignment, comparison, logical, bitwise, spread/rest, and optional‑chaining operators. Use === and !== for strict comparison to avoid coercion surprises.

// Optional chaining & nullish coalescing
const userName = profile?.account?.name ?? 'Anonymous';

4 · Control Flow Statements

Conditionals: if, else if, else, and switch. Loops: for, for…in, for…of, while, do…while.

// for…of iterates over iterable values
for (const [currency, rate] of Object.entries(rates)){
    console.log(`${currency}: ${rate}`);
}

5 · Functions & Arrow Syntax

Function declarations hoist; function expressions do not. Arrow functions () => keep the surrounding this context.

// Arrow function with implicit return
const sum = (a, b) => a + b;

// Rest parameters & default values
function log(level = 'info', ...messages){
    console[level](...messages);
}

6 · Objects & Prototype Chain

Every object inherits from Object.prototype unless created with Object.create(null). Use Object.getPrototypeOf() and Object.setPrototypeOf() to inspect/modify chains.

// Shorthand property & method names
const x = 10;
const obj = {
    x,                          // same as x: x
    double(){ return this.x*2; } // concise method
};

7 · ES2015 Classes & Inheritance

Classes are syntactic sugar over prototypes. Note: class bodies are executed in strict mode.

class Animal{
    constructor(name){ this.name = name; }
    speak(){ console.log(`${this.name} makes a noise.`); }
}

class Dog extends Animal{
    speak(){ super.speak(); console.log('Woof!'); }
}

new Dog('Rex').speak();

8 · Modules (ESM & CommonJS)

ES Modules use import/export; CommonJS uses require()/module.exports.

// math.js (ESM)
export function add(a, b){ return a + b; }

// main.mjs
import { add } from './math.js';
console.log(add(2, 3));

9 · Asynchronous Patterns

Callbacks → Promises → async/await. A promise is a thenable representing a future value.

// Fetch with async/await
try{
    const res = await fetch('/api/data');
    if(!res.ok) throw new Error(res.statusText);
    const json = await res.json();
    console.log(json);
}catch(err){
    console.error(err);
}

10 · Error Handling & Exceptions

Use try…catch…finally. Custom errors extend the built‑in Error class.

class ValidationError extends Error{
    constructor(message){
        super(message);
        this.name = 'ValidationError';
    }
}

function assertEmail(str){
    if(!/^\S+@\S+\.\S+$/.test(str)){
        throw new ValidationError('Invalid email');
    }
}

11 · Standard Built‑in Objects & Methods

Core globals: Array, Map, Set, Date, RegExp, Math, etc. Many provide static utility methods such as Array.from() or Object.assign().

// Array helpers
const arr = [1,2,3,4];
const evens = arr.filter(n => n % 2 === 0);
const sum  = arr.reduce((a,b) => a+b, 0);

12 · Strict Mode & Directives

Add "use strict" at the top of a script or function to opt into safer semantics: disallow silent errors, catch unsafe actions (e.g., implicit globals).

"use strict";
undeclared = 1;   // ReferenceError (thanks, strict mode)

13 · Comments & Documentation

Single‑line: // comment   |   Multi‑line: /* … */. JSDoc adds type hints and metadata understood by IDEs and TypeScript.

/**
 * Multiplies two numbers.
 * @param {number} a
 * @param {number} b
 * @returns {number}
 */
function multiply(a, b){ return a * b; }

14 · Best Practices & Patterns

Enforce a linter (ESLint), adopt const-first, use template literals, avoid global scope, and modularize code. Note: prefer === over ==; avoid with and eval.

// Module pattern via IIFE
const Utils = (() => {
    function clamp(num, min, max){
        return Math.min(Math.max(num, min), max);
    }
    return { clamp };
})();
export default Utils;