12 / 20 · Day 4
Day 4 · Concept 12

Classes

ES6 classes are syntactic sugar over the prototype system. Cleaner than the old function Foo() {...} + Foo.prototype.bar = ... dance. Still need to understand prototypes for debugging.


1 · The basics

js class.js
class User {
    constructor(name, age) {
        this.name = name;
        this.age = age;
    }

    greet() {
        return `hi, ${this.name}`;
    }

    // Static — on the class, not instances
    static fromObject({ name, age }) {
        return new User(name, age);
    }
}

const u = new User("Alice", 30);
console.log(u.greet());
const u2 = User.fromObject({ name: "Bob", age: 25 });
console.log(u2.greet());

2 · Inheritance with extends

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

class Dog extends Animal {
    speak() { return `${this.name} barks`; }
    fetch() { return `${this.name} fetches`; }
}

const d = new Dog("Rex");
console.log(d.speak());
console.log(d.fetch());

// super calls the parent
class Cat extends Animal {
    speak() { return super.speak() + " (meow)"; }
}
console.log(new Cat("Whiskers").speak());

3 · Private fields and getters/setters

js private.js
class Counter {
    #count = 0;   // # = private, not accessible outside the class

    get value() { return this.#count; }

    increment() { this.#count += 1; }

    set value(n) {
        if (n < 0) throw new Error("must be >= 0");
        this.#count = n;
    }
}

const c = new Counter();
c.increment();
c.increment();
c.value = 10;
console.log(c.value);
// c.#count;   // SyntaxError outside the class

4 · Class fields and arrow methods

js fields.js
class Button {
    label = "Click";
    clickCount = 0;

    // Arrow as class field — bound to the instance automatically
    onClick = () => {
        this.clickCount += 1;
        console.log(`${this.label}: ${this.clickCount}`);
    };
}

const b = new Button();
const handler = b.onClick;   // detach
handler();                    // still works — bound
handler();

Useful in React class components for event handlers — but classes themselves are uncommon in modern React (function components dominate).

5 · Classes vs factory functions

ClassFactory function
Familiar syntax for OOP coming from Java/C#No new, no this, simpler
instanceof worksNot directly
Prototype chain — extension possibleNo inheritance chain
Better tooling (inspectors show class)Lighter, no new mistakes

Modern JS frequently uses factories for data objects and classes for things with state + behaviour (parsers, services, frameworks).

6 · Common mistakes

  • Forgetting new. User("x") without new throws.
  • Class methods losing this when detached. Use arrow class fields or bind in the constructor.
  • Mutating shared prototype properties. Class methods are on the prototype — mutating User.prototype.foo affects all instances.

7 · When it clicks

  • You pick class vs factory based on whether you need extends or instanceof.
  • Private fields with # are reflex when you want true encapsulation.
  • You recognise classes are sugar — and can debug the prototype chain when needed.
Found this useful?