Introduction
ES6 classes provide a cleaner syntax for creating objects and implementing inheritance. While they're syntactic sugar over JavaScript's prototype system, they make object-oriented patterns more accessible and code more readable.
Key Concepts
Class: A template for creating objects with shared methods and structure.
Constructor: A special method for initializing new instances.
Instance: An object created from a class using new.
Real World Context
UI components, data models, game entities, API clients—classes organize complex codebases. React class components (legacy), TypeScript, and many libraries use classes extensively.
Deep Dive
Basic Class Syntax
javascriptclass User { // Constructor - called when using 'new' constructor(name, email) { this.name = name; this.email = email; this.createdAt = new Date(); } // Instance method greet() { return `Hello, I'm ${this.name}`; } // Getter get displayName() { return `${this.name} <${this.email}>`; } // Setter set displayName(value) { const [name, email] = value.split(' <'); this.name = name; this.email = email.replace('>', ''); } } const user = new User('Alice', 'alice@example.com'); user.greet(); // 'Hello, I'm Alice' user.displayName; // 'Alice <alice@example.com>'
Static Members
javascriptclass MathUtils { static PI = 3.14159; static square(n) { return n * n; } static cube(n) { return n * n * n; } } // Called on class, not instances MathUtils.PI; // 3.14159 MathUtils.square(4); // 16 const m = new MathUtils(); // m.square(4); // Error - static methods aren't on instances
Public and Private Fields (ES2022)
javascriptclass BankAccount { // Public field owner; // Private field (# prefix) #balance = 0; constructor(owner, initialBalance) { this.owner = owner; this.#balance = initialBalance; } deposit(amount) { if (amount > 0) this.#balance += amount; } get balance() { return this.#balance; // Controlled access } // Private method #validateTransaction(amount) { return amount > 0 && amount <= this.#balance; } } const account = new BankAccount('Alice', 100); account.balance; // 100 // account.#balance; // SyntaxError - private!
Class Expressions
javascript// Named class expression const MyClass = class ClassName { constructor() { /* ... */ } }; // Anonymous class expression const AnonClass = class { constructor() { /* ... */ } };
Common Pitfalls
- Forgetting
new: Classes throw withoutnew(unlike constructor functions). - Arrow methods for
this: Class methods aren't auto-bound; use arrows in constructor or bind. - Private fields require declaration:
#fieldmust be declared in class body.
Best Practices
- Use private fields for internal state: Encapsulation prevents external manipulation.
- Use getters for computed properties: Instead of method calls.
- Use static for utility methods: That don't need instance data.
- Keep classes focused: Single responsibility principle.
Summary
Classes provide a clean syntax for object-oriented JavaScript. Use constructor for initialization, define methods in the class body, and use static for class-level members. ES2022's private fields (#) enable true encapsulation. Always use new when instantiating classes.
Code Examples
class User {
// Constructor - called when using 'new'
constructor(name, email) {
this.name = name;
this.email = email;
this.createdAt = new Date();
}
// Instance method
greet() {
return `Hello, I'm ${this.name}`;
}
// Getter
get displayName() {
return `${this.name} <${this.email}>`;
}class MathUtils {
static PI = 3.14159;
static square(n) {
return n * n;
}
static cube(n) {
return n * n * n;
}
}
// Called on class, not instances
MathUtils.PI; // 3.14159
MathUtils.square(4); // 16
const m = new MathUtils();
// m.square(4); // Error - static methods aren't on instances