Source: https://cs.au.dk/~hosc/local/LaSC-4-3-pp223-242.pdf
Sometimes the behavior of an instance of a data type can be divided into several different “modes” of behavior or implementation…
A self-reorganizing collection might use radically different representations depending on recent access patterns, such as whether insertion has been more or less frequent than indexing, even though the external interface to the collection remains unchanged…
One common way of capturing different behavioral modes is to include a flag instance variable defining the behavior mode, and testing the flag at the beginning of each method that depends on the behavior mode. This obscures the code for each behavior mode, merging all behavior modes into shared methods that are sprinkled with if-tests and case-statements…
This code is analogous to programs simulating object-oriented method dispatching: if-tests and case-statements are used to determine the type of the receiver of a “message.” Not surprisingly, flag tests for behavior modes suffer from the same problems as flag tests for receiver types: it is hard to add new behavior modes without modifying lots of code, it is error-prone to write, and it is difficult to understand a particular mode since its code is intermixed with code for other behavior modes…
A better way of implementing behavior modes is to define each mode as its own special subtype of the general data type, and use method dispatching and inheritance to eliminate the flag tests.:
For example, the collection data type could be refined into an empty collection data type and a non-empty collection data type, using inheritance to relate the three types... However, the behavior mode of an instance may change as its state changes: an empty collection becomes non-empty if an element is added to it.… Most class-based languages do not allow an object to change its class, and those that do face hard problems.… Classless languages, on the other hand, can be naturally extended to handle dynamically-changing behavior modes by allowing an object’s parents to change at run-time;…
Behavior modes are naturally implemented in classless languages by using dynamic inheritance to choose from a small set of parents. This style of programming does not compromise the structure of the system; on the contrary, it can make the structure and organization of the system clearer by separating out the various modes of behavior. In contrast, the close coupling between a class and its representation prevent class-based languages from being extended naturally to handle behavior modes.
Note: I've purposely left out the sections that promote changing the representation dynamically, i.e. totally changing the interface at runtime, as having methods appearing and disappearing certainly does seem horribly pain-inducing, but so long as the underlying structures have compatible interfaces, this seems to me to be a very powerful pattern that we can almost harness in JavaScript, were it not for the gratuitous performance costs and disgust from our peers.