Magento 2 Experten — Hyvä Theme, Tailwind CSS & SEO aus einer Hand ›

Object-Oriented Programming With Classes in JavaScript

Object-Oriented Programming With Classes in JavaScript

~14 Min. Lesezeit Zuletzt aktualisiert am August 8, 2026

With class, JavaScript builds a familiar, object-oriented syntax on top of its actual prototype system (chapter 20). Let's now model an Account that manages our budget app in a structured way.

The first class: Account

src/account.js
export class Account {
  constructor(name, startingBalance) {
    this.name = name;
    this.balance = startingBalance;
    this.transactions = [];
  }

  record(description, amount, category) {
    this.balance += amount;
    this.transactions.push({ description, amount, category });
  }

  formatBalance() {
    return `${this.name}: ${this.balance.toFixed(2)} EUR`;
  }
}
src/index.js
import { Account } from './account.js';

const account = new Account('Checking', 1500);
account.record('January salary', 2400, 'Salary');
account.record('January rent', -850, 'Rent');

console.log(account.formatBalance()); // 'Checking: 3050.00 EUR'
console.log(account.transactions.length);  // 2

constructor runs automatically on EVERY new Account(...) call and initializes the instance properties. Methods like record() are SHARED across ALL instances of the class (via the prototype, chapter 20) – not recreated for every new instance.

Getters and setters

Computed properties that LOOK like regular properties but are actually methods:

class Account {
  constructor(name, startingBalance) {
    this.name = name;
    this._balance = startingBalance; // convention: '_' signals 'don't use directly'
  }

  get balance() {
    return this._balance;
  }

  set balance(newValue) {
    if (newValue < 0) {
      throw new Error('Balance cannot be set to a negative value');
    }
    this._balance = newValue;
  }
}

const account = new Account('Checking', 1500);
console.log(account.balance); // 1500 - reads like a normal property, but calls get()
account.balance = 2000;       // writes like a normal property, but calls set()
account.balance = -50;        // Error: Balance cannot be set to a negative value

Real private fields with #

Since ES2022, JavaScript supports REAL privacy at the language level – unlike the _ convention above (which only expresses a STYLISTIC intent, but is still technically accessible from outside), a field marked with # is truly INACCESSIBLE from outside the class:

class Account {
  #balance; // real private field

  constructor(name, startingBalance) {
    this.name = name;
    this.#balance = startingBalance;
  }

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

const account = new Account('Checking', 1500);
console.log(account.balance);   // 1500 - via the getter
console.log(account.#balance);  // SyntaxError - directly impossible from outside!

Tipp: This is the modern, language-native alternative to the closure-based "private state" from chapter 16 – for classes, # is the preferred approach today.

Static methods and properties

static members belong to the CLASS itself, not to a single instance – useful for helper functions that logically belong to the class but don't need access to a specific instance:

class Account {
  static CURRENCY = 'EUR';

  static createEmptyAccount(name) {
    return new Account(name, 0);
  }

  constructor(name, startingBalance) {
    this.name = name;
    this.balance = startingBalance;
  }
}

console.log(Account.CURRENCY); // 'EUR' - accessed via the CLASS, not an instance

const newAccount = Account.createEmptyAccount('Savings');
console.log(newAccount.balance); // 0

class vs. object literal: when which?

ToolWhen it fits
Object literal (chapter 12)For SINGLE, one-off data structures with no behavior or little shared logic – e.g. a single transaction.
classWhen SEVERAL similar instances are needed with shared behavior (methods) and encapsulated, validated state – e.g. multiple accounts with booking logic.