闭包构建轻量级状态容器,通过封装私有状态与 getstate、setstate、subscribe 三个基础 api 实现隔离、无依赖、可复用的状态管理,支持多实例、模块化及渐进增强。

用闭包构建轻量级状态容器,核心是把状态变量和操作方法封装在函数作用域内,只暴露可控的接口。它不依赖任何外部库,没有全局污染,每个实例彼此隔离,适合表单、弹窗、计数器等局部场景。
封装私有状态与基础 API
状态变量定义在闭包内部,外部无法直接访问;通过返回对象暴露 getState、setState 和 subscribe 三个基本方法:
- getState 返回当前状态的只读快照(建议返回结构化副本,避免引用泄露)
- setState 接收新状态或更新函数,执行后触发所有监听器
- subscribe 允许注册回调,并返回取消订阅的清理函数
示例实现:
let state = initialState;
const listeners = [];
return {
getState: () => ({ ...state }),
setState: (update) => {
state = typeof update === 'function'
? update(state)
: { ...state, ...update };
listeners.forEach(cb => cb());
},
subscribe: (cb) => {
listeners.push(cb);
return () => {
const i = listeners.indexOf(cb);
if (i > -1) listeners.splice(i, 1);
};
}
};
}
支持多实例与模块复用
每次调用 createStore 都生成独立闭包,状态互不干扰。适合组件级封装:
- 一个表单组件可创建自己的 store 实例,避免与其他表单共享状态
- 结合 ES Module 导出工厂函数,天然适配 tree-shaking 和按需加载
- 若需预设结构(如带校验的字段),可进一步封装 makeField、makeForm 等辅助函数
绑定视图更新逻辑
闭包本身不自动刷新 UI,需手动桥接状态变更与渲染:
- 在 setState 后直接调用 render()(适用于原生 DOM 或简单模板)
- 在 React 中,可在自定义 Hook 内部 subscribe 并触发 useState 的更新
- 为防频繁重绘,可用 requestAnimationFrame 节流通知,或加 shallow diff 判断是否真有变化
增强能力:不可变更新与监听过滤
轻量不等于简陋,可渐进增强关键能力:
- setState 默认做浅合并,也支持传入函数式更新(prev => ({ count: prev.count + 1 }))
- subscribe 可扩展为支持 selector:subscribe(cb, (state) => state.count),仅当目标字段变化才触发
- 添加 reset、patch、getIn 等实用方法,仍保持接口简洁、无副作用











