对比对象数组并修改属性的JavaScript代码是否为最高效实现?
问题分析与优化方案
现有实现的问题
- 逻辑缺陷:核心判断逻辑
Object.values(field).includes(true)完全没有和必填字段数组做匹配,仅依赖对象引用相同时提前给RequiredFields加的required:true属性才能跑对结果,只要两个数组的对象是不同引用、哪怕fieldApiName完全匹配也会判断错误,属于逻辑硬伤 - 存在副作用:直接修改了入参
RequiredFields和Allfields里的原对象,如果其他业务逻辑依赖原数组数据会触发不可预期的错误 - 效率偏低:如果后续需要通过匹配
fieldApiName修正逻辑,直接双重遍历的时间复杂度是O(n*m),数据量较大时性能很差
最优实现方案
推荐使用Set存储必填字段的唯一标识fieldApiName,整体时间复杂度降为O(n+m),同时采用纯函数写法不修改原数据:
const RequiredFields = [ { fieldApiName: 'FirstName', value: 'Test' } , { fieldApiName: 'LastName', value: 'LastNameTest' } ] const AllFields = [ { fieldApiName: 'FirstName', value: 'Test' } , { fieldApiName: 'LastName', value: 'LastNameTest' } , { fieldApiName: 'Suffix', value: '' } ] const addRequiredFields = (requiredFields, allFields) => { // 存储必填字段api名,查找复杂度O(1) const requiredApiSet = new Set(requiredFields.map(item => item.fieldApiName)); // 返回新数组新对象,不修改原数据 return allFields.map(field => ({ ...field, required: requiredApiSet.has(field.fieldApiName) })); } console.log(addRequiredFields(RequiredFields, AllFields))
运行后完全符合你给出的预期输出。
方案优势
- 逻辑严谨:仅通过
fieldApiName匹配必填项,不受对象引用是否相同的影响 - 性能最优:仅需要两次线性遍历,适合大数组场景
- 无副作用:不会修改入参的原数组、原对象,符合ES6组件中数据不可变的最佳实践
- 代码精简易读,维护成本低
内容的提问来源于stack exchange,提问作者thinker
相关产品推荐
相关产品推荐

