Photo by PJH on Unsplash

On this page

This chapter follows Prototypes and inheritance.

Classes in ECMAScript are constructor functions with cleaner syntax. Under the hood, methods are still on the prototype; new still sets [[Prototype]] and runs the constructor body.

Class declaration and constructor

class Rectangle {
constructor(width, height) {
this.width = width;
this.height = height;
}
area() {
return this.width * this.height;
}
}
const r = new Rectangle(3, 4);
r.area(); // 12

Class bodies run in strict mode. Hoisting differs from function declarations: the class binding sits in the temporal dead zone until the class declaration executes.

extends and super

extends sets up the prototype chain between .prototype objects and adds super for calling the parent constructor or methods.

class Square extends Rectangle {
constructor(side) {
super(side, side);
}
}

super() must run in a derived constructor before this is used.

Instance fields, static members, and private fields

Public instance fields install own properties in the constructor phase:

class Counter {
count = 0;
increment() {
this.count++;
}
}

Static methods and fields belong to the constructor object (Counter.parse(...)). Private names use # and are enforced by the language—only code in the class body can read #secret.

Getters, setters, and methods

Method shorthand in a class body defines enumerable prototype methods (unlike defineProperty defaults). Getters and setters use the same syntax as in object literals.

Classes versus factory functions

Use classes when you want instanceof, a stable prototype, and familiar OOP layout. Use closures and factory functions when you want private state without # or when instances are cheap one-offs. Both are idiomatic; pick based on API surface and team style.

Next: QuickTip: Freezing and sealing objects.

Search articles

Type a word to search published articles.

Open the search page