OOP & Classes in JavaScript - Exercise 3

A static method belongs to the class itself rather than to individual instances.

class MathTools {
  static double(value) { return value * 2; }
}
console.log(MathTools.double(4));

Use the static keyword for data shared by the class rather than stored on each instance.

class User {
  static role = 'member';
}
console.log(User.role);

Composition combines focused capabilities without creating a rigid parent-child hierarchy.

const canLog = (object) => ({
  log(message) { console.log(message); return object; }
});
const service = canLog({ name: 'Orders' });

Keep state private and expose methods that validate every update.

class Progress {
  #value = 0;
  advance(step) {
    this.#value = Math.min(100, Math.max(0, this.#value + step));
  }
  get value() { return this.#value; }
}

It assigns an initial value directly in the class body before the constructor continues.

class Cart {
  items = [];
  currency = 'USD';
  add(item) { this.items.push(item); }
}

Use an arrow-function field or bind the method when passing it as a callback.

class Timer {
  seconds = 0;
  tick = () => { this.seconds += 1; };
}
setInterval(new Timer().tick, 1000);

Keep responsibilities focused, document the public contract, and avoid exposing mutable internal state.

class Repository {
  findById(id) { return this.records.find(record => record.id === id); }
  constructor(records = []) { this.records = [...records]; }
}

Use the simplest abstraction that fits. A plain object or function is often clearer when there is no shared lifecycle, identity, or behavior to model.

function formatPrice(amount, currency = 'USD') {
  return new Intl.NumberFormat('en', { style: 'currency', currency }).format(amount);
}