闭包在状态机设计中核心作用是把当前状态和转移逻辑封装在函数作用域内,避免全局变量污染,同时让状态私有且持久可变。

闭包在状态机设计中核心作用是**把当前状态和转移逻辑封装在函数作用域内,避免全局变量污染,同时让状态私有且持久可变**。它不依赖 class 或 this,仅靠函数嵌套 + 变量引用就能自然维持运行时状态。
用闭包封装状态与 transition 函数
定义一个工厂函数,返回包含 当前状态 和 可调用的转移方法 的对象。内部状态变量(如 state)被闭包捕获,外部无法直接访问,只能通过暴露的方法操作:
function createStateMachine(initialState, rules) {
let state = initialState;
return {
getState() { return state; },
transition(event) {
const next = rules[state]?.[event];
if (next !== undefined) {
state = next;
}
return state;
}
};
}
// 使用示例
const light = createStateMachine('off', {
off: { press: 'on' },
on: { press: 'off' }
});
light.getState(); // 'off'
light.transition('press'); // 'on'
light.transition('press'); // 'off'
闭包支持带副作用或条件的状态转移
规则不只是查表映射,还可包含业务逻辑:比如需要校验、计数、异步等待、或根据上下文动态决定下一个状态。这些逻辑共享同一个闭包环境,天然访问当前状态和私有变量:
function createLoginMachine() {
let state = 'idle';
let attemptCount = 0;
return {
getState() { return state; },
login() {
if (state === 'idle') {
state = 'authenticating';
}
},
onSuccess() {
if (state === 'authenticating') {
state = 'logged_in';
attemptCount = 0;
}
},
onError() {
if (state === 'authenticating') {
attemptCount++;
state = attemptCount >= 3 ? 'locked' : 'idle';
}
}
};
}
多个独立状态机实例互不干扰
每次调用工厂函数都生成新闭包,每个实例拥有自己的一套 state、attemptCount 等变量。这比用 class 实例更轻量,也比全局对象更安全:
-
const userA = createLoginMachine()和const userB = createLoginMachine()各自维护独立状态 - 没有原型链、this 绑定或 new 调用开销
- 适合函数式风格或配置驱动的状态管理场景(如表单步骤、动画帧控制、协议解析器)
配合高阶函数实现状态行为注入
把状态响应逻辑(如进入某状态时触发回调)也闭包化,形成“状态 + 行为”的组合单元:
function createStatefulMachine(initial, handlers) {
let state = initial;
return {
go(to) {
const from = state;
state = to;
handlers?.[from]?.exit?.();
handlers?.[to]?.enter?.();
return state;
}
};
}
const player = createStatefulMachine('idle', {
idle: { enter: () => console.log('→ idle') },
walk: { enter: () => console.log('→ walking') }
});
player.go('walk'); // → walking
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











