A single variable (often named `temp`, `result`, `value`) reassigned multiple times to hold conceptually distinct values — perimeter, then area; current iteration result, then accumulator.
Each variable has one role; reassignment patterns reflect distinct purposes rather than reused storage.
Before the refactoring
let temp = 2 * (height + width);console.log(temp);temp = height * width;console.log(temp);
After the refactoring
const perimeter = 2 * (height + width);console.log(perimeter);const area = height * width;console.log(area);
The reader must track which role the variable currently holds; bugs hide where one role's update accidentally clobbers another; refactoring either use is impossible without disentangling.
If the two uses were actually coupled — shared init or synchronized update — splitting them invites drift the single mutation kept in sync.
Names match purpose; the type system can narrow each role; refactoring each use becomes local.
Splitting variables whose uses were genuinely coupled — accumulator that depends on a previous-iteration version of itself — fragments coherent state into separate variables that have to re-establish the coupling.