ES6 class 重构状态模式的核心是用私有字段#currentState统一状态源、Map实现查表式迁移、钩子解耦副作用,并提供语义化业务方法。

用 ES6 class 重构传统状态模式,核心不是照搬 C 或 Java 的多类结构,而是借 class 的封装能力,把“状态流转”这件事收束到一个可读、可测、易维护的单一实体中。关键在于放弃“每个状态一个类”的重量级做法,转而用私有状态字段 + 映射表 + 受控迁移方法,实现逻辑集中但职责分明。
用私有字段锁定唯一状态源
避免状态散落在 this.state、this.status、this.mode 等多个属性里。统一用私有字段(如 #currentState)保存当前状态,并禁止外部直接修改:
- 构造时初始化:this.#currentState = initialState;
- 所有变更必须走 transition(event) 方法,不暴露 setter;
- 配合 Symbol 或常量枚举(如 STATES.IDLE)定义状态值,防止字符串拼写错误。
用 Map 替代 if-else 实现转移逻辑
不再在 transition() 里写一长串 switch 或嵌套判断。把状态迁移规则提前声明为二维映射:
- 结构示例:this.#transitions = new Map([ [STATES.IDLE, new Map([[EVENT.START, STATES.LOADING]])] ]);
- 迁移时只需查表:const next = this.#transitions.get(this.#currentState)?.get(event);
- 查不到就抛错,明确提示非法操作,而不是静默失败或进入未知状态。
把副作用收进钩子,而非塞进状态类
传统状态模式常让每个状态类承担副作用(比如 API 请求、UI 提示),导致类膨胀且难以复用。ES6 class 更适合将副作用解耦:
立即学习“前端免费学习笔记(深入)”;
- 定义 #onEnter(state, prevState) 和 #onExit(prevState) 钩子;
- 在 transition() 内部按序调用,确保行为与状态严格同步;
- 允许外部通过 on('enter', handler) 订阅,用于日志、埋点或 React 状态同步。
与 React 协同时只暴露语义化动作
组件不关心状态机内部怎么跳转,只调用高阶语义方法:
- 状态机提供 start()、cancel()、retry() 等业务方法;
- 这些方法内部调用 transition(EVENT.START),封装了事件名和校验逻辑;
- 组件用 useMemo(() => new FormStateMachine(), []) 创建实例,用 useState(machine.state) 消费状态。
不复杂但容易忽略


















