Before 2015, building an object model in JavaScript meant a constructor function, some prototype work and a fair amount of patience.
class gathered all of that into one declaration. The underlying mechanism did not change, the readability did.
Definition
class declares a model from which objects will be built with new. The declaration brings together the constructor, the methods shared by every instance, and the fields that belong to each one.
class Cart {
#items = [];
add(name, price) {
this.#items.push({ name, price });
return this;
}
get total() {
return this.#items.reduce((sum, item) => sum + item.price, 0);
}
}
const cart = new Cart();
cart.add("Keyboard", 79).add("Mouse", 29);
console.log(cart.total); // 108Three things deserve attention here. The #items field is private and does not exist outside the class. Each method returns this, which is what allows the calls to be chained. And total reads like an ordinary property even though a calculation runs on every read.
What a class can contain
A class body does not accept just anything: no commas between members, no free-standing statements. Here is the complete list of what may appear inside.
| Element | Role |
|---|---|
| constructor | Prepares the instance at creation time |
| Method | Behavior shared by every instance |
| Field | Data owned by each instance, declared at the top |
| Field prefixed with a hash | Data that is strictly unreachable from outside |
| get and set | A computed property behind an ordinary read |
| static member | Attached to the class itself, not to instances |
The private field is the addition that changes the most day to day: where a leading underscore was only a convention, the hash is enforced by the language, and any access from outside is refused while the file is being parsed.
Sugar on top of prototypes
A class introduces no new machinery in the engine. It produces a function, and its methods land on the prototype, exactly as before.
class Dog {
bark() { return "Woof"; }
}
const rex = new Dog();
console.log(typeof Dog); // "function"
console.log(Object.getPrototypeOf(rex) === Dog.prototype); // trueTwo behavioral differences are still worth knowing. A class body always runs in strict mode, even inside a file that is not. And a class cannot be used before its declaration: unlike a function, it stays unreachable until the line that defines it.
Frequently asked questions
Do you need classes to write good JavaScript?
No. A function returning an object literal is often enough, and a great deal of modern code stops there. A class becomes interesting when several objects share behavior, when state has to stay private, or when a family of types emerges through extends.
Can a method be added after the declaration?
Technically yes, by writing onto the prototype of the class, and every existing instance inherits it immediately. It is a practice to avoid in application code: the declaration stops telling the truth about what the class can do, and analysis tools no longer follow.
Are TypeScript classes the same thing?
They are the same classes, extended with annotations checked at compile time: field types, visibility, read-only properties. The code produced remains ordinary JavaScript. Our TypeScript course goes through what those annotations catch and what they cannot catch.