Skip to content
Plurafy

Class Syntax and OOP

Understanding ES6 classes and object-oriented programming in JavaScript

You need to create reusable, maintainable code using object-oriented principles. How do you use ES6 classes effectively while avoiding common pitfalls?

ES6 classes provide syntactic sugar over JavaScript’s prototype-based inheritance. While they compile to the same prototype model, they offer a cleaner, more familiar syntax for developers from other OOP languages.

class Animal {
constructor(name) {
this.name = name;
}
speak() {
console.log(`${this.name} makes a sound`);
}
// Static methods
static info() {
return 'This is an animal class';
}
}
const dog = new Animal('Rex');
dog.speak(); // Rex makes a sound
console.log(Animal.info()); // This is an animal class
// Classes are functions
console.log(typeof Animal); // function
class Animal {
constructor(name) {
this.name = name;
}
eat(food) {
console.log(`${this.name} eats ${food}`);
}
}
class Dog extends Animal {
constructor(name, breed) {
super(name); // Call parent constructor
this.breed = breed;
}
bark() {
console.log('Woof!');
}
// Override parent method
eat(food) {
super.eat(food); // Call parent method
console.log('Yummy!');
}
}
const dog = new Dog('Buddy', 'Labrador');
dog.eat('food');
// "Buddy eats food"
// "Yummy!"
class User {
constructor(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
this._age = 0;
}
// Getter
get fullName() {
return `${this.firstName} ${this.lastName}`;
}
// Setter
set fullName(name) {
[this.firstName, this.lastName] = name.split(' ');
}
get age() {
return this._age;
}
set age(value) {
if (value < 0 || value > 150) {
console.log('Invalid age');
return;
}
this._age = value;
}
}
const user = new User('John', 'Doe');
console.log(user.fullName); // John Doe
user.fullName = 'Jane Smith';
console.log(user.firstName); // Jane
user.age = 30;
console.log(user.age); // 30
user.age = 200; // Logs: Invalid age
class BankAccount {
#balance = 0; // Private field
constructor(initialBalance) {
this.#balance = initialBalance;
}
// Private method
#calculateInterest() {
return this.#balance * 0.05;
}
// Public method
deposit(amount) {
this.#balance += amount;
return this.#balance;
}
getBalance() {
return this.#balance;
}
getInterest() {
return this.#calculateInterest();
}
}
const account = new BankAccount(1000);
account.deposit(500);
console.log(account.getBalance()); // 1500
// Can't access private fields
console.log(account.#balance); // SyntaxError
console.log(account._balance); // undefined
class Logger {
static #instances = 0;
static level = 'info';
constructor(name) {
this.name = name;
Logger.#instances++;
}
static getInstance(name) {
return new Logger(name);
}
static getInstanceCount() {
return Logger.#instances;
}
static setLevel(level) {
Logger.level = level;
}
log(message) {
console.log(`[${this.name}] ${message}`);
}
}
const log1 = Logger.getInstance('App');
const log2 = Logger.getInstance('Database');
console.log(Logger.getInstanceCount()); // 2
Logger.setLevel('debug');
class Database {
constructor() {
// Prevent instantiation
if (this.constructor === Database) {
throw new Error('Cannot instantiate abstract class');
}
}
// Abstract method
query(sql) {
throw new Error('query() must be implemented');
}
// Concrete method
close() {
console.log('Closing connection');
}
}
class PostgreSQL extends Database {
query(sql) {
// Implementation
console.log(`Executing PostgreSQL: ${sql}`);
}
}
// const db = new Database(); // Error!
const pgDb = new PostgreSQL();
pgDb.query('SELECT * FROM users');
class EventEmitter {
constructor() {
this.events = {};
}
on(event, listener) {
if (!this.events[event]) {
this.events[event] = [];
}
this.events[event].push(listener);
}
emit(event, ...args) {
if (!this.events[event]) return;
this.events[event].forEach(listener => {
listener(...args);
});
}
off(event, listenerToRemove) {
if (!this.events[event]) return;
this.events[event] = this.events[event].filter(
listener => listener !== listenerToRemove
);
}
}
class Button extends EventEmitter {
click() {
this.emit('click', { timestamp: Date.now() });
}
}
const button = new Button();
button.on('click', (data) => console.log('Clicked at', data.timestamp));
button.click();