Useful Cheatsheetsusefulcheatsheets.com
JavaScript Classes
Chapter 14 · Page 113
Intermediate

JavaScript Classes

Build objects with class syntax covering constructors, inheritance, static members, and private fields.

TL;DR

  1. 01Define object blueprints with class and constructor syntax.
  2. 02Inherit shared behavior using extends and super() calls.
  3. 03Hide internal state with private fields marked by #.

Tips

  1. 01Use private fields with a hash prefix to stop outside code from reading or changing internal state directly.
  2. 02Call super() before using this in a subclass constructor, since the parent must initialize the instance first.
  3. 03Prefer static methods for utility functions that relate to a class but don't need a specific instance.

Warnings

  1. 01Forgetting to call super() in a subclass constructor throws a ReferenceError before this can be accessed.
  2. 02Arrow function class fields capture this permanently, which can surprise developers expecting normal method binding rules.
  3. 03Class declarations are not hoisted like functions, so using a class before its definition throws an error.
Notes
Useful Cheatsheetsusefulcheatsheets.com
JavaScript Classes
Chapter 14 · Page 114
Intermediate

JavaScript Classes

(continued)

Class Basics

  • class + constructor

    Define a blueprint for creating objects with shared methods.

    class User {
      constructor(name, email) {
        this.name = name;
        this.email = email;
      }
    }
  • new keyword

    Create instances with new, which runs the constructor automatically.

    const user = new User('Ana', 'ana@example.com');
    console.log(user.name); // "Ana"
  • Instance methods

    Define instance methods inside the class body without the function keyword.

    class User {
      constructor(name) {
        this.name = name;
      }
      greet() {
        return `Hi, ${this.name}`;
      }
    }
  • Shared prototype

    Methods live on the prototype, so every instance shares one copy instead of duplicating.

    const a = new User('Ana');
    const b = new User('Leo');
    console.log(a.greet === b.greet); // true
  • Strict mode

    Class declarations run in strict mode automatically, catching more silent bugs.

    class Demo {
      constructor() {
        undeclaredVar = 1; // throws ReferenceError in strict mode
      }
    }
  • No hoisting

    Classes are not hoisted the way function declarations are, so define them before use.

    // new Greeter() here would throw a ReferenceError
    class Greeter {}
Notes
Useful Cheatsheetsusefulcheatsheets.com
JavaScript Classes
Chapter 14 · Page 115
Intermediate

JavaScript Classes

(continued)

Static Methods and Properties

  • static method

    Mark a method static to attach it to the class itself instead of each instance.

    class MathHelper {
      static square(n) {
        return n * n;
      }
    }
    MathHelper.square(4); // 16
  • No instance this

    Static methods cannot access instance data through this because no instance exists.

    class Counter {
      static count = 0;
      constructor() {
        Counter.count++;
      }
    }
  • Shared data

    Use static properties to track data shared across all instances, like a running total.

    new Counter();
    new Counter();
    console.log(Counter.count); // 2
  • Factory methods

    Build factory methods as static functions that return configured instances.

    class User {
      static fromJSON(json) {
        const data = JSON.parse(json);
        return new User(data.name, data.email);
      }
    }
  • Static blocks

    Static blocks let you run setup logic once when the class is first defined.

    class Config {
      static settings;
      static {
        Config.settings = loadDefaults();
      }
    }
Notes
Useful Cheatsheetsusefulcheatsheets.com
JavaScript Classes
Chapter 14 · Page 116
Intermediate

JavaScript Classes

(continued)

Getters, Setters, and Private Fields

  • get

    Define a property that computes its value each time it's read.

    class Circle {
      constructor(radius) {
        this.radius = radius;
      }
      get area() {
        return Math.PI * this.radius ** 2;
      }
    }
  • set

    Run logic, like validation, whenever a property is assigned.

    class Circle {
      set radius(value) {
        if (value <= 0) throw new RangeError('Radius must be positive');
        this._radius = value;
      }
    }
  • Private fields (#)

    Mark fields private with a leading # so they can't be read or changed outside the class.

    class BankAccount {
      #balance = 0;
      deposit(amount) {
        this.#balance += amount;
      }
      get balance() {
        return this.#balance;
      }
    }
  • Enforced privacy

    Accessing a private field from outside the class throws a SyntaxError, not just undefined.

    const acc = new BankAccount();
    acc.#balance; // SyntaxError: Private field must be declared in an enclosing class
  • Private methods

    Private methods work the same way, hiding internal logic from the public API.

    class Order {
      #calculateTax(amount) {
        return amount * 0.08;
      }
      getTotal(amount) {
        return amount + this.#calculateTax(amount);
      }
    }
Notes
Useful Cheatsheetsusefulcheatsheets.com
JavaScript Classes
Chapter 14 · Page 117
Intermediate

JavaScript Classes

(continued)

Inheritance with Extends and Super

  • extends

    Create a subclass that inherits methods and properties from a parent.

    class Animal {
      constructor(name) {
        this.name = name;
      }
      speak() {
        return `${this.name} makes a sound`;
      }
    }
    class Dog extends Animal {}
  • super()

    Call super() inside a subclass constructor to run the parent constructor first.

    class Dog extends Animal {
      constructor(name, breed) {
        super(name);
        this.breed = breed;
      }
    }
  • Overriding methods

    Override a parent method by redefining it with the same name in the subclass.

    class Dog extends Animal {
      speak() {
        return `${this.name} barks`;
      }
    }
  • super.method()

    Call super.methodName() to reuse parent logic instead of duplicating it.

    class Dog extends Animal {
      speak() {
        return `${super.speak()} loudly`;
      }
    }
  • instanceof

    Check whether an object inherits from a given class.

    const rex = new Dog('Rex', 'Lab');
    console.log(rex instanceof Animal); // true
Notes
Useful Cheatsheetsusefulcheatsheets.com
JavaScript Classes
Chapter 14 · Page 118
Intermediate

JavaScript Classes

(continued)

Classes vs Prototypes

  • Syntactic sugar

    Classes are syntactic sugar over JavaScript's existing prototype-based inheritance model.

    class Point {
      constructor(x, y) {
        this.x = x;
        this.y = y;
      }
    }
    // Roughly equivalent to a constructor function + prototype assignment
  • Methods on prototype

    A class method becomes a non-enumerable property on the constructor's prototype object.

    class Point {
      distanceTo(other) {
        return Math.hypot(this.x - other.x, this.y - other.y);
      }
    }
    console.log(typeof Point.prototype.distanceTo); // "function"
  • typeof a class

    The typeof a class is still "function", confirming classes are functions under the hood.

    console.log(typeof Point); // "function"
  • Requires new

    Unlike old-style constructor functions, classes throw an error if called without new.

    function OldStyle() {}
    OldStyle(); // works (but usually a bug)
    
    class NewStyle {}
    NewStyle(); // TypeError: Class constructor cannot be invoked without 'new'
Notes
Useful Cheatsheetsusefulcheatsheets.com
JavaScript Classes
Chapter 14 · Page 119
Intermediate

JavaScript Classes

(FAQ)

FAQ

A class field declares a property directly on the class body, and it runs before the constructor body executes. A constructor assignment sets the property inside the constructor function instead. Both end up creating the same instance property, but fields are often shorter for simple defaults.

Yes, classes compile down to the same prototype-based inheritance JavaScript always used. Methods defined in a class body are added to the prototype, not to each instance. Classes simply give that pattern cleaner, more familiar syntax.

An underscore prefix like _name is just a convention; outside code can still access it. A true private field written as #name is enforced by the engine. Accessing it from outside the class throws an error, so private fields offer real encapsulation, not just a hint.

Use a static method when the logic doesn't depend on a specific instance, like a factory function or a helper. Static methods are called on the class itself, such as MyClass.create(). Instance methods need this to refer to specific object data.

No, a class cannot have a field and an accessor pair with the same name; that throws a SyntaxError. Pick one approach: a plain field for simple storage, or a getter/setter pair for computed values. Use accessors when you need validation logic too.

Useful Cheatsheetsusefulcheatsheets.com
JavaScript Classes
Chapter 14 · Page 120
Intermediate

JavaScript Classes

(In Practice)
In Practice

Modeling a Savings Account with Inheritance

A SavingsAccount subclass extends a base Account class, using super(), a private field, and a getter to apply interest safely.

  1. 01Account keeps #balance private, exposing it only through a read-only balance getter.
  2. 02SavingsAccount extends Account and calls super() to initialize the shared owner and balance fields.
  3. 03applyInterest() reads this.balance through the inherited getter, then calls the inherited deposit() method.
  4. 04instanceof confirms SavingsAccount still inherits from Account despite adding its own behavior.
class Account {
  #balance;
  constructor(owner, balance = 0) {
    this.owner = owner;
    this.#balance = balance;
  }
  deposit(amount) {
    this.#balance += amount;
    return this.#balance;
  }
  get balance() {
    return this.#balance;
  }
}

class SavingsAccount extends Account {
  constructor(owner, balance, rate) {
    super(owner, balance);
    this.rate = rate;
  }
  applyInterest() {
    const interest = this.balance * this.rate;
    return this.deposit(interest);
  }
}

const savings = new SavingsAccount('Priya', 1000, 0.05);
savings.applyInterest();
console.log(savings.balance); // 1050
console.log(savings instanceof Account); // true
Takeaway

extends plus super() lets a subclass reuse private state and methods it can't access directly.