JavaScript用闭包实现状态机的核心是利用闭包捕获并持久化状态变量,使状态不随函数调用结束而丢失;通过返回的函数接口控制状态迁移和行为响应,支持条件守卫、副作用触发与通用配置化扩展,且各实例状态完全隔离。

JavaScript 中用闭包实现状态机的状态保存,核心是利用闭包捕获并持久化状态变量,让状态不随函数调用结束而丢失,同时通过返回的函数接口控制状态迁移和行为响应。
用闭包封装私有状态和转移逻辑
把当前状态(如 currentState)定义在外部函数作用域中,内部返回的方法共享该变量。每次调用返回的函数时,都能读写这个被闭包“记住”的状态。
例如实现一个简单的灯开关状态机:
function createLightMachine() {
let state = 'off'; // 私有状态,被闭包持有
return {
turnOn() {
if (state === 'off') {
state = 'on';
console.log('灯已打开');
}
},
turnOff() {
if (state === 'on') {
state = 'off';
console.log('灯已关闭');
}
},
getState() {
return state;
}
};
}
const light = createLightMachine();
light.turnOn(); // 灯已打开
light.turnOn(); // 无反应(状态不变)
light.turnOff(); // 灯已关闭
console.log(light.getState()); // 'off'
支持带条件的状态迁移和事件驱动
可在动作方法中加入守卫条件(guard)、副作用(如日志、回调)或返回迁移结果,让状态机更贴近实际使用场景。
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
立即学习“Java免费学习笔记(深入)”;
- 每个方法可检查是否允许当前操作,避免非法迁移
- 状态变更后可触发回调,比如通知 UI 更新:
onStateChange?.(newState) - 返回布尔值或对象(如
{ ok: true, from: 'off', to: 'on' })便于上层处理
扩展为通用状态机构造器
把状态集合、初始状态、迁移规则抽成配置,用闭包维持运行时状态,提升复用性:
function createStateMachine(config) {
const { states, initial, transitions } = config;
let currentState = initial;
return {
getState() { return currentState; },
send(event) {
const next = transitions[currentState]?.[event];
if (next && states.includes(next)) {
const prev = currentState;
currentState = next;
return { type: 'transition', from: prev, to: next };
}
return { type: 'ignored', event, state: currentState };
}
};
}
// 使用示例
const trafficLight = createStateMachine({
states: ['red', 'yellow', 'green'],
initial: 'red',
transitions: {
red: { TIMER: 'green' },
green: { TIMER: 'yellow' },
yellow: { TIMER: 'red' }
}
});
注意闭包状态的隔离性与内存管理
每次调用工厂函数都会创建独立的闭包作用域,不同实例间状态完全隔离——这是优势,也是设计前提。
- 避免意外共享:不要把状态变量放在全局或模块顶层
- 若需长期运行且状态复杂,留意闭包中引用的大对象,防止内存泄漏
- 必要时提供
reset()方法显式重置闭包内状态

















