Modern JavaScript Class-Based Object Orientation and Inheritance
Class Declaration and Instantiation
ES6 introduced the class syntax for defining objects with shared properties and methods. A class serves as a blueprint for creating instances.
// Define a class using the class keyword
class Musician {
// Constructor method executed during instantiation
constructor(artistName, yearsActive) {
this.artistName = artistName;
this.yearsActive = yearsActive;
}
}
// Create instances using the new keyword
const elvis = new Musician("Elvis Presley", 25);
const john = new Musician("John Lennon");
console.log(elvis); // Musician {artistName: "Elvis Presley", yearsActive: 25}
console.log(john); // Musician {artistName: "John Lennon", yearsActive: undefined}
Class naming follows PascalCase convention. The constructor method automatically executes when creating instances with new. Parameters passed to new are forwarded to the constructor.
Adding Methods to Classes
Methods within classes don't require the function keyword and aren't separated by commas:
class Performer {
constructor(name, experience) {
this.name = name;
this.experience = experience;
}
perform(track) {
console.log(`${this.name} performs ${track}`);
}
}
const artist = new Performer("Michael Jackson", 40);
artist.perform("Billie Jean"); // Michael Jackson performs Billie Jean
Class Inheritance
Classes can inherit properties and methods from parent classes using the extends keyword:
class Artist {
funds() {
console.log(10000);
}
}
class Painter extends Artist {
// Inherits all methods from Artist
}
const painterInstance = new Painter();
painterInstance.funds(); // 10000
Using the super Keyword
The super keyword allows access to parent class functionality:
Calling Parent Constructors
class Creator {
constructor(width, height) {
this.width = width;
this.height = height;
}
calculateArea() {
console.log(this.width * this.height);
}
}
class Designer extends Creator {
constructor(width, height) {
super(width, height); // Pass parameters to parent constructor
}
}
const designer = new Designer(5, 10);
designer.calculateArea(); // 50
When a child class has its own constructor, super() must be called before accessing this.
Invoking Parent Methods
class Animal {
speak() {
return 'Animal sound';
}
}
class Dog extends Animal {
speak() {
return `${super.speak()} - specifically barking`;
}
}
const dog = new Dog();
console.log(dog.speak()); // Animal sound - specifically barking
Extending Parent Functionality
Child classes can both inherit and extend parent behavior:
class Calculator {
constructor(a, b) {
this.a = a;
this.b = b;
}
add() {
console.log(this.a + this.b);
}
}
class AdvancedCalculator extends Calculator {
constructor(a, b) {
super(a, b);
}
subtract() {
console.log(this.a - this.b);
}
}
const calc = new AdvancedCalculator(8, 3);
calc.add(); // 11
calc.subtract(); // 5
Context Binding in Classes
The this context within class methods depends on how they're invoked:
class Component {
constructor(title) {
this.title = title;
this.element = document.createElement('div');
this.element.textContent = this.title;
// Preserve class context when assigning event handlers
this.element.addEventListener('click', this.handleClick.bind(this));
}
handleClick() {
console.log(`Clicked: ${this.title}`);
}
}
const widget = new Component('Dashboard');
// Clicking the element will correctly log "Clicked: Dashboard"
In event handlers and callbacks, this typcially refers to the calling object rather than the class instance, requiring explicit binding.