Capture and restore an object's internal state, without exposing that state to the outside world.
Implementing undo naively often means exposing an object's internal fields publicly so something else can copy and later restore them — which also means anything else can now freely mutate that internal state, breaking the object's own invariants.
The originator creates a memento — an opaque snapshot object — of its own state and can restore from one later. A separate caretaker (like a history stack) stores mementos but never looks inside them or modifies them directly.
`History` stores mementos but never reads their contents — only `Editor` knows how to create or apply them.
class Editor {
#text = "";
type(str) { this.#text += str; }
get content() { return this.#text; }
save() {
return { restore: (target) => { target.#text = this.#text; } };
// returns an opaque memento closing over the current state
}
}
class History {
#snapshots = [];
push(memento) { this.#snapshots.push(memento); }
undo(editor) { this.#snapshots.pop()?.restore(editor); }
}
const editor = new Editor();
const history = new History();
editor.type("Hello");
history.push(editor.save());
editor.type(", world");
console.log(editor.content); // "Hello, world"
history.undo(editor);
console.log(editor.content); // "Hello"