React中如何提取对象变更字段供PATCH请求使用,有哪些实现方法或库?
解决方案
前置注意事项
你的示例代码存在两处需要修正的问题:
let dynamicObject = obj属于对象引用赋值,两个变量指向同一块内存地址,修改obj的属性等同于修改dynamicObject。如果要保留原始对象用于对比,需要先对初始对象做拷贝:// 单层对象用浅拷贝即可 let originalObj = {...obj}; // 多层嵌套对象可用深拷贝,也可以用lodash的cloneDeep方法 // let originalObj = JSON.parse(JSON.stringify(obj));- 示例里的
createdBy = 'ken'属于全局变量赋值,正确写法应为obj.createdBy = 'ken',否则不会修改到对象的对应属性。
现成库方案
Lodash 实现(最常用)
绝大多数前端项目都已引入Lodash,直接用内置方法组合即可实现需求,同时支持深浅对比,兼容单层/嵌套复杂对象的场景:
import _ from 'lodash'; function getChangedFields(original, updated) { return _.pickBy(updated, (value, key) => !_.isEqual(value, original[key])); }
通用手动实现方案
如果不想引入第三方依赖,可以根据业务场景选择对应实现:
浅比较版本(适用于单层对象、字段值都是基础类型的场景)
即你示例中的使用场景,实现逻辑简单性能高:
function getChangedFields(original, updated) { const changed = {}; for (const key in updated) { // hasOwnProperty判断用于过滤掉原型链上的属性,不需要可删除 if (updated.hasOwnProperty(key) && original.hasOwnProperty(key) && updated[key] !== original[key]) { changed[key] = updated[key]; } } return changed; }
深比较版本(适用于包含嵌套对象、数组的复杂对象场景)
function deepEqual(a, b) { if (a === b) return true; if (typeof a !== 'object' || a === null || typeof b !== 'object' || b === null) return false; const keysA = Object.keys(a), keysB = Object.keys(b); if (keysA.length !== keysB.length) return false; for (const key of keysA) { if (!keysB.includes(key) || !deepEqual(a[key], b[key])) return false; } return true; } function getChangedFieldsDeep(original, updated) { const changed = {}; for (const key in updated) { if (updated.hasOwnProperty(key) && original.hasOwnProperty(key) && !deepEqual(updated[key], original[key])) { changed[key] = updated[key]; } } return changed; }
内容的提问来源于stack exchange,提问作者CCCC
相关产品推荐
相关产品推荐

