Sling Academy
Home/JavaScript/Bringing OOP Sensibilities into JavaScript with Class Syntax

Bringing OOP Sensibilities into JavaScript with Class Syntax

Last updated: December 12, 2024

JavaScript, a language primarily known for its prototypal inheritance model, has evolved significantly over the years. One of the most prominent additions to ECMAScript 6 (ES6) was the class syntax, bringing an object-oriented programming (OOP) flavor that appeals to developers coming from traditional OOP languages like Java and C++. Let's delve deeper into how JavaScript’s class syntax helps structure code in an OOP manner.

Introduction to JavaScript Classes

Before ES6, JavaScript didn't have any formal class syntax. Developers used functions to create constructor functions and prototypes to add methods. This approach, though effective, often appeared cumbersome compared to traditional class-based languages.

// Pre-ES6 Constructor function
function Person(name, age) {
    this.name = name;
    this.age = age;
}

Person.prototype.greet = function() {
    return `Hello, my name is ${this.name}`;
};

const p1 = new Person('John', 30);
console.log(p1.greet());

With the introduction of classes in ES6, JavaScript's syntax became more elegant and aligned well with other OOP languages:

// ES6 Class Syntax
class Person {
    constructor(name, age) {
        this.name = name;
        this.age = age;
    }

    greet() {
        return `Hello, my name is ${this.name}`;
    }
}

const p2 = new Person('Jane', 25);
console.log(p2.greet());

Understanding Constructor and Methods

In ES6, the constructor method is a special method for creating and initializing an object created with a class. Each class can only have one special method with the name "constructor".

  • The constructor is automatically called when a new instance of the class is created.
  • This is where you define values or add properties significant for your object.
  • The methods within the class don’t need to be prefixed; they blend directly into the class definition as seen with greet in the example above.

Inheritance in JavaScript Classes

One of the key pillars of OOP is inheritance, and JavaScript classes make it straightforward to implement inheritance using the extends keyword.

// Inheritance Example
class Employee extends Person {
    constructor(name, age, position) {
        super(name, age); // Calling the parent constructor
        this.position = position;
    }

    work() {
        return `${this.name} is working as a ${this.position}`;
    }
}

const e1 = new Employee('Tom', 34, 'Developer');
console.log(e1.greet());
console.log(e1.work());

When creating a child class using extends, you call the parent constructor with super(), ensuring the parent class initializes properties appropriately. This familiar concept to those with an OOP background helps in making JavaScript more accessible and its code, more structured.

Encapsulation and Privacy

Mainstream OOP languages support encapsulation allowing data hiding, but JavaScript's class syntax doesn't natively support private class fields until recent updates (e.g., class field declarations with # for private).

// Private fields in classes
class BankAccount {
    #balance;
    constructor(initialBalance) {
        this.#balance = initialBalance;
    }

    deposit(amount) {
        if(amount > 0) {
            this.#balance += amount;
        }
    }

    getBalance() {
        return this.#balance;
    }
}

const account = new BankAccount(100);
account.deposit(50);
console.log(account.getBalance()); // Expected: 150
console.log(account.#balance); // Syntax Error: Private field

By prepending a #, you make a field private, meaning it can only be accessed within the enclosing class. This strategy allows us to encapsulate our object’s data appropriately.

Conclusion

JavaScript's class syntax is more than just syntactical sugar mirroring the functional underpinnings of the language, it provides a readable, accessible way to structure code and embrace OOP concepts. Whether you're refactoring old JavaScript code or building from scratch, using classes will make your code more intuitive, enhancing its maintainability and scaling potential. By fully utilizing ES6 class syntax—inclusively of constructors, inheritance, and private fields—you align closer to traditional OOP paradigms, harnessing both readability and performance.

Next Article: Repurposing Existing Code as Flexible JavaScript Classes

Previous Article: Accelerating Refactors by Consolidating Logic into JavaScript Classes

Series: JavaScript Classes

JavaScript

You May Also Like

  • Handle Zoom and Scroll with the Visual Viewport API in JavaScript
  • Improve Security Posture Using JavaScript Trusted Types
  • Allow Seamless Device Switching Using JavaScript Remote Playback
  • Update Content Proactively with the JavaScript Push API
  • Simplify Tooltip and Dropdown Creation via JavaScript Popover API
  • Improve User Experience Through Performance Metrics in JavaScript
  • Coordinate Workers Using Channel Messaging in JavaScript
  • Exchange Data Between Iframes Using Channel Messaging in JavaScript
  • Manipulating Time Zones in JavaScript Without Libraries
  • Solving Simple Algebraic Equations Using JavaScript Math Functions
  • Emulating Traditional OOP Constructs with JavaScript Classes
  • Smoothing Out User Flows: Focus Management Techniques in JavaScript
  • Creating Dynamic Timers and Counters with JavaScript
  • Implement Old-School Data Fetching Using JavaScript XMLHttpRequest
  • Load Dynamic Content Without Reloading via XMLHttpRequest in JavaScript
  • Manage Error Handling and Timeouts Using XMLHttpRequest in JavaScript
  • Handle XML and JSON Responses via JavaScript XMLHttpRequest
  • Make AJAX Requests with XMLHttpRequest in JavaScript
  • Customize Subtitle Styling Using JavaScript WebVTT Integration