JavaScript Cheatsheet
Classes
Use this JavaScript reference while you build software engineering projects, review code for technical interview prep, or polish examples for a software engineer resume.
Class Declaration
class Animal { // Public class field (ES2022) species = "unknown"; constructor(name, sound) { this.name = name; this.sound = sound; } // Instance method speak() { return `${this.name} says ${this.sound}`; } // Getter get info() { return `${this.name} (${this.species})`; } // Setter set info(val) { [this.name] = val.split(" "); } // Static method — called on class, not instance static create(name) { return new Animal(name, "..."); } // toString for coercion toString() { return this.name; } } const dog = new Animal("Rex", "woof"); dog.speak() // "Rex says woof" Animal.create("Cat") // Animal instance
Class Expression
// Named class expression (name only in scope inside) const Animal = class AnimalClass { constructor(name) { this.name = name; } }; // Anonymous class expression const Animal2 = class { constructor(name) { this.name = name; } };
Public and Private Fields (ES2022)
class Counter { // Public field with default count = 0; // Private field — only accessible inside the class body #step; #history = []; constructor(step = 1) { this.#step = step; } increment() { this.count += this.#step; this.#history.push(this.count); return this; } get history() { return [...this.#history]; } // Private method #validate(n) { return Number.isInteger(n) && n > 0; } // Static private static #instances = 0; static getCount() { return Counter.#instances; } } const c = new Counter(2); c.increment().increment(); c.count // 4 c.#step // SyntaxError — private "#step" in c // false (private field check)
Static Members
class MathUtils { // Static field static PI = 3.14159; // Static method static square(n) { return n * n; } static cube(n) { return n ** 3; } // Static getter static get version() { return "1.0"; } } MathUtils.PI // 3.14159 MathUtils.square(4) // 16 MathUtils.version // "1.0" // Static block (ES2022) — complex initialization class Config { static DEBUG; static { Config.DEBUG = process.env.NODE_ENV !== "production"; } }
Inheritance
class Dog extends Animal { constructor(name, breed) { super(name, "woof"); // must call super() before using `this` this.breed = breed; } // Override speak() { return super.speak() + "!"; // call parent method } fetch() { return `${this.name} fetches the ball`; } } const rex = new Dog("Rex", "Labrador"); rex.speak() // "Rex says woof!" rex instanceof Dog // true rex instanceof Animal // true // Check prototype chain Object.getPrototypeOf(Dog.prototype) === Animal.prototype // true
Inheritance with Private Fields
class Base { #value; constructor(v) { this.#value = v; } getValue() { return this.#value; } } class Derived extends Base { #extra; constructor(v, extra) { super(v); this.#extra = extra; } getAll() { return [this.getValue(), this.#extra]; } }
Getters and Setters
class Temperature { #celsius; constructor(celsius) { this.#celsius = celsius; } get celsius() { return this.#celsius; } set celsius(val) { if (val < -273.15) throw new RangeError("Below absolute zero"); this.#celsius = val; } get fahrenheit() { return this.#celsius * 9/5 + 32; } set fahrenheit(val) { this.#celsius = (val - 32) * 5/9; } get kelvin() { return this.#celsius + 273.15; } } const t = new Temperature(100); t.fahrenheit // 212 t.celsius = -10; t.kelvin // 263.15
Mixins
// Mixin — add reusable behavior via Object.assign to prototype const Serializable = (Base) => class extends Base { serialize() { return JSON.stringify(this); } static deserialize(json) { return Object.assign(new this(), JSON.parse(json)); } }; const Validatable = (Base) => class extends Base { validate() { return Object.keys(this).every(k => this[k] !== null); } }; class Model {} class User extends Serializable(Validatable(Model)) { constructor(name, age) { super(); this.name = name; this.age = age; } } const u = new User("Alice", 30); u.serialize(); // '{"name":"Alice","age":30}' u.validate(); // true
Abstract-Like Patterns
// JavaScript has no abstract keyword — enforce in constructor class Shape { constructor() { if (new.target === Shape) { throw new TypeError("Cannot instantiate abstract class Shape"); } } // Abstract method — must be overridden area() { throw new Error("area() must be implemented"); } toString() { return `${this.constructor.name}(area=${this.area()})`; } } class Circle extends Shape { #r; constructor(r) { super(); this.#r = r; } area() { return Math.PI * this.#r ** 2; } } new Shape() // TypeError new Circle(5).area() // 78.53...
Class vs Function Constructor
// ES5 constructor function function PersonOld(name) { this.name = name; } PersonOld.prototype.greet = function() { return `Hi, ${this.name}`; }; // ES6 class (syntactic sugar over prototype chain) class Person { constructor(name) { this.name = name; } greet() { return `Hi, ${this.name}`; } } // Both produce same prototype structure: const p = new Person("Alice"); typeof Person // "function" Person.prototype.greet // exists p.__proto__ === Person.prototype // true // Key difference: classes must be called with new; functions don't enforce it
Useful Patterns
// Fluent interface (method chaining) class QueryBuilder { #table = ""; #conditions = []; #limit = null; from(table) { this.#table = table; return this; } where(cond) { this.#conditions.push(cond); return this; } limit(n) { this.#limit = n; return this; } build() { let q = `SELECT * FROM ${this.#table}`; if (this.#conditions.length) q += ` WHERE ${this.#conditions.join(" AND ")}`; if (this.#limit !== null) q += ` LIMIT ${this.#limit}`; return q; } } new QueryBuilder().from("users").where("age > 18").limit(10).build(); // "SELECT * FROM users WHERE age > 18 LIMIT 10" // Singleton class Singleton { static #instance = null; static getInstance() { if (!Singleton.#instance) Singleton.#instance = new Singleton(); return Singleton.#instance; } } // Factory method class Animal2 { static create(type, name) { switch (type) { case "dog": return new Dog(name); case "cat": return new Cat(name); default: throw new Error(`Unknown type: ${type}`); } } }
Symbol.iterator and Custom Iterables
class Range { constructor(start, end, step = 1) { this.start = start; this.end = end; this.step = step; } [Symbol.iterator]() { let current = this.start; const { end, step } = this; return { next() { if (current < end) { const value = current; current += step; return { value, done: false }; } return { value: undefined, done: true }; }, }; } } const r = new Range(1, 10, 2); [...r] // [1, 3, 5, 7, 9] for (const n of r) console.log(n);