A command object packages an operation with its arguments. Because the operation becomes data, an invoker can schedule it, keep a history for undo, cancel or batch it, or serialize it for another machine. Editor undo stacks and collaborative editing (operational transformation) build on this pattern.
const feed = new Set(); // the receiver
class Post { // a command: action + arguments
constructor(text) { this.text = text; }
execute() { feed.add(this.text); } undo() { feed.delete(this.text); }
toJSON() { return { type: 'post', text: this.text }; } // serializable for the network
}
class Invoker {
#history = [];
run(cmd) { cmd.execute(); this.#history.push(cmd); }
undo() { this.#history.pop()?.undo(); }
}
const inv = new Invoker();
['Hi!', 'Typo!'].forEach((text) => inv.run(new Post(text))); inv.undo();
console.log([...feed], JSON.stringify(new Post('Later')));[ 'Hi!' ] {"type":"post","text":"Later"}