With that said, this seems like a recipe for debugging nightmares. Getters and setters already make life difficult, hiding statefulness and complexity in a way that’s not apparent at the call site (you don’t even know it’s a call site!). Adding magic where sometimes a value is computed and sometimes it’s not amplifies those problems.
Maybe my FP is showing, but all of this could be much more easily accomplished with plain value type data structures and functions. Computed values can be derived either at construction time (ideal, fewer nullish properties and less chance of passing incomplete values off to something that expects them to be complete) or by passing the structure to a function (or calling a method if you must, but here `this` is just an implicit argument to allow access to other properties of the structure).
Replacing a computed value is as simple as constructing a new value structure with the value set explicitly.
All of that is a lot easier to reason about (in terms of just reading the source to see what it does), almost certainly has better performance characteristics, and definitely makes concurrency less complex.
These principles work very well in a general FP environment, but they can be applied to great benefit even in more imperative environments like JS.