将状态处理逻辑放原型上可避免函数重复创建,1000个实例共享一份方法;状态数据须区分共享(如initialstate)与独有(如currentstate);用object.create实现轻量继承;外部状态通过参数传入或weakmap管理。

直接把状态处理逻辑放在原型上,所有状态机实例共用同一套方法,不重复创建函数对象,内存占用就能压到最低。
状态方法统一挂到 prototype 上
不要在构造函数里写 this.transition = function() {},否则每个状态机实例都会生成独立函数。正确做法是:
- 单个添加:StateMachine.prototype.transition = function(to) { ... };
- 批量定义(记得补 constructor):StateMachine.prototype = { constructor: StateMachine, transition() { ... }, getState() { ... } };
这样 1000 个状态机实例,transition 函数只占一份内存空间。验证方式:打印 sm1.transition === sm2.transition,结果为 true。
状态数据严格区分“共享”与“独有”
原型适合放不变的配置和通用行为,但不能放可变状态:
- ✅ 共享:默认初始状态 StateMachine.prototype.initialState = 'idle';、状态映射表 StateMachine.prototype.transitions = { idle: ['loading', 'error'] };
- ❌ 禁止共享:当前状态值 this.currentState 必须定义在实例上(this.currentState = 'idle'),否则多个实例会互相覆盖
引用类型如数组或对象若放在原型上,所有实例会共用同一份内存,导致状态污染。
用 Object.create 实现原型委托式轻量拷贝
当需要派生子状态机(比如带不同超时策略的变体),别用深拷贝,改用原型链委托:
- const fastSM = Object.create(baseSM); —— 新实例不复制方法,只继承 baseSM 的 prototype
- 仅覆盖差异字段:fastSM.timeout = 500;,其余行为自动沿原型链查找
- 访问 fastSM.transition 时,引擎直接命中原型上的函数,无额外分配
这种方式比 new StateMachine() 更轻,尤其适合高频创建/销毁的场景(如动画帧状态、表单校验器)。
配合享元思想管理外部状态
状态机本身只管流程逻辑,具体业务数据(如用户 ID、请求参数)应作为外部状态传入,不固化在实例中:
- 方法签名设计为 transition(to, context),context 是运行时传入的临时数据
- 避免在 this 上缓存 context 对象,防止闭包捕获导致堆内存膨胀
- 必要时用 WeakMap 关联外部状态,确保不阻碍垃圾回收
这样状态机实例真正变成“纯逻辑壳”,体积可控,复用率高。










