数组状态同步核心是比对新旧数组识别增删留三类操作,用Set提升简单值查找效率,对象数组依赖唯一键判断,历史快照可生成变更日志。

用数组实现状态同步,核心是把“旧状态”和“新状态”看作两个数组,通过比对找出哪些该加、哪些该删、哪些可保留。不需要框架或复杂库,几行逻辑就能跑通常见场景,比如标签管理、用户权限开关、订单持仓同步等。
明确比对目标:增、删、不变三类操作
状态同步不是覆盖重写,而是精准干预。一次比对应能回答三个问题:
- 哪些项在旧数组里有、新数组里没了?→ 需删除
- 哪些项在新数组里有、旧数组里没有?→ 需添加
- 哪些项两边都有且内容一致?→ 可跳过(或用于校验)
例如旧权限列表['read', 'edit'],新列表['read', 'delete'],那么'edit'要删,'delete'要加,'read'保持不变。
基础数组:用 Set 提升查找效率
对字符串、数字这类简单值,避免嵌套循环。用 Set 预存一个数组的值,再遍历另一个数组做 O(1) 查找:
const old = ['a', 'b', 'c']; const current = ['b', 'c', 'd']; const oldSet = new Set(old); const currentSet = new Set(current); const toAdd = current.filter(item => !oldSet.has(item)); // ['d'] const toRemove = old.filter(item => !currentSet.has(item)); // ['a']
这种方式简洁、易读、性能好,适合几百项以内的日常同步。
对象数组:靠唯一键做存在性判断
当数组元素是对象(如{id: 1, name: '张三'}),不能直接用 === 或 JSON.stringify 比较。必须选定一个稳定字段(通常是 id 或 uuid)作为锚点:
const oldUsers = [{id: 1, name: '张三'}, {id: 2, name: '李四'}];
const currentUsers = [{id: 1, name: '张三丰'}, {id: 3, name: '王五'}];
const oldIds = new Set(oldUsers.map(u => u.id));
const currentIds = new Set(currentUsers.map(u => u.id));
const added = currentUsers.filter(u => !oldIds.has(u.id));
const removed = oldUsers.filter(u => !currentIds.has(u.id));
const updated = currentUsers.filter(u => oldIds.has(u.id) &&
JSON.stringify(u) !== JSON.stringify(oldUsers.find(old => old.id === u.id))
);
注意:updated 判断用了 JSON.stringify 是为快速示意;生产环境建议只比关键字段,或用浅比较函数,避免深嵌套开销。
变量版本差异:用数组存历史快照
想追踪某个变量(比如配置对象)的变更过程?可以把每次变更后的值推入一个数组,然后对相邻两项做差异提取:
- 定义 versions = [v0, v1, v2],其中每项是完整状态对象
- 对 versions[i] 和 versions[i+1] 调用上述对象数组比对逻辑
- 结果可生成变更日志:“第2次更新:新增字段 timeout,修改 retry 从 3 → 5”
这种模式天然适配配置灰度、表单修改记录、甚至简易版 undo/redo。










