Classes (ES6+)
Introduced in ECMAScript 2015 (ES6), JavaScript classes provide a much simpler and clearer syntax to create objects and deal with inheritance. It's important to note that JavaScript classes are primarily syntactic sugar over the existing prototype-based inheritance model; they do not introduce a new object-oriented inheritance model to JavaScript.
1. Class Syntax and Constructor
A class is defined using the class keyword. The constructor is a special method used for initializing an object created with a class.
class Person {
// The constructor runs when you use 'new Person()'
constructor(name, age) {
this.name = name;
this.age = age;
}
// Instance method (added to the prototype)
greet() {
console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`);
}
}
const alice = new Person("Alice", 30);
alice.greet(); // Hello, my name is Alice and I am 30 years old.
2. Getters and Setters
You can define getters and setters to intercept read and write access to properties, enabling data validation or computed properties.
class User {
constructor(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
// Getter
get fullName() {
return `${this.firstName} ${this.lastName}`;
}
// Setter
set fullName(newName) {
const parts = newName.split(' ');
this.firstName = parts[0];
this.lastName = parts[1];
}
}
const user = new User("John", "Doe");
console.log(user.fullName); // "John Doe"
user.fullName = "Jane Smith";
console.log(user.firstName); // "Jane"
3. Static Methods and Properties
Static methods and properties belong to the class itself, not to instances of the class. They are often used for utility functions.
class MathUtils {
static PI = 3.14159;
static square(number) {
return number * number;
}
}
console.log(MathUtils.PI); // 3.14159
console.log(MathUtils.square(4)); // 16
// Cannot be called on an instance
// const utils = new MathUtils();
// utils.square(4); // TypeError
4. Inheritance and super
Classes can inherit from other classes using the extends keyword. The super keyword is used to call the constructor or methods of the parent class.
class Animal {
constructor(name) {
this.name = name;
}
speak() {
console.log(`${this.name} makes a noise.`);
}
}
class Dog extends Animal {
constructor(name, breed) {
// Call the parent constructor FIRST
super(name);
this.breed = breed;
}
// Method overriding
speak() {
console.log(`${this.name} barks.`);
}
}
const dog = new Dog("Rex", "German Shepherd");
dog.speak(); // "Rex barks."
5. Private Fields and Methods
Modern JavaScript (ES2022) introduced true private class features using the # prefix. Private fields and methods cannot be accessed from outside the class.
class BankAccount {
// Private field
#balance = 0;
constructor(initialBalance) {
this.#balance = initialBalance;
}
deposit(amount) {
this.#balance += amount;
this.#logTransaction('Deposit', amount);
}
// Private method
#logTransaction(type, amount) {
console.log(`${type}: $${amount}. New balance: $${this.#balance}`);
}
getBalance() {
return this.#balance;
}
}
const account = new BankAccount(100);
account.deposit(50); // Deposit: $50. New balance: $150
console.log(account.getBalance()); // 150
// console.log(account.#balance); // SyntaxError: Private field '#balance' must be declared in an enclosing class
Summary
class: Blueprint for creating objects.constructor: Initializes instance properties.- Methods: Functions added to the prototype.
get/set: Property accessors.static: Attached to the class, not instances.extends/super: Prototypal inheritance and parent reference.#: True private fields and methods.