
onDone = callback (Single Callback)class Animal {
  constructor(name) {
    this.name = name;
    // A single callback property (can be assigned later)
    this.onDone = null;
  }
  performAction() {
    console.log(`${this.name} is running...`);
    // If the callback exists, call it
    if (this.onDone) {
      this.onDone(`${this.name} finished the action.`);
    }
  }
}
// Create instance
const dog = new Animal("Milo");
// Assign a callback function to be called when action is done
dog.onDone = (message) => {
  console.log("Callback received:", message);
};
dog.performAction();
onDone(callback) (Multiple Callbacks)class Animal {
  constructor(name) {
    this.name = name;
    // A list of callbacks to notify when done
    this._onDoneCallbacks = [];
  }
  // Method for registering a callback
  onDone(callback) {
    this._onDoneCallbacks.push(callback);
  }
  performAction() {
    console.log(`${this.name} is running...`);
    // Call all registered callbacks
    for (const cb of this._onDoneCallbacks) {
      cb(`${this.name} finished the action.`);
    }
  }
}
// Create instance
const dog = new Animal("Luna");
// Register multiple callbacks
dog.onDone((message) => console.log("Logger 1:", message));
dog.onDone((message) => console.log("Logger 2:", message));
dog.performAction();
| Feature | onDone = callback | onDone(callback) | 
|---|---|---|
| Simplicity | ✅ Simple | ❌ Slightly more involved | 
| Supports multiple callbacks | ❌ No | ✅ Yes | 
| Familiar for beginners | ✅ Yes | ⚠️ Slightly abstract | 
| Scales well | ❌ Not really | ✅ Yes | 
| Style | Declarative | Event-driven | 
| Reassignable | ✅ Yes | ✅ Yes (via multiple calls) | 

Thanks for reading! ^_^