JavaScript如何检索对象指定属性列表中不存在的首个或全部属性
批量校验对象属性存在性的优化实现
原实现存在两个可优化的点:
- 方法语义不匹配:
Array.map的设计初衷是通过遍历生成等长的映射数组,用它执行带副作用的校验逻辑、手动向外部数组push值的写法,违背了方法的设计意图,可读性较差。 - 判断逻辑存在偏差:原代码用
!block.name这类真值判断校验属性,会把「属性真实存在但值为falsy(比如空字符串、数字0、布尔false)」的场景误判为属性缺失,不符合“精准校验属性存在性”的核心需求。
适配当前业务需求的优化方案
首先把需要校验的必填属性抽成可配置的常量,后续调整校验规则时不需要修改核心判断逻辑:
// 配置需要校验的属性清单,增减校验项直接修改这个数组即可 const REQUIRED_PROPS = ['name', 'formula', 'id'];
兼容性提示:如果需要精准判断属性存在,优先使用
Object.hasOwn(block, prop)方法,相比直接调用block.hasOwnProperty更可靠,能避免对象本身覆写了该方法、或者是null原型对象带来的判断异常。如果需要兼容更低版本的浏览器,可以替换为Object.prototype.hasOwnProperty.call(block, prop)。
1. 全量收集所有无效块的序号(兼容原实现的输出格式)
可以用减少可变状态的写法,也可以保留手动遍历的习惯,两种实现的输出和原代码完全一致,不需要调整下游引用逻辑:
- 低可变状态的方法链实现:
const invalidBlocks = blocks .map((block, index) => ({ block, seq: index + 1 })) .filter(({ block }) => { // 只要块对象上缺少任意一个必填属性,就标记为无效 return REQUIRED_PROPS.some(prop => !Object.hasOwn(block, prop)); }) .map(({ seq }) => seq);
- 贴近原写法的遍历实现:
let invalidBlocks = []; blocks.forEach((block, index) => { const hasAllRequiredProps = REQUIRED_PROPS.every(prop => Object.hasOwn(block, prop)); if (!hasAllRequiredProps) { invalidBlocks.push(index + 1); } });
2. 快速定位首个无效块
如果业务只需要找到第一个校验不通过的块,不需要遍历完整个数组,可以用find方法提前终止遍历,性能更好:
const firstInvalidBlockIndex = blocks.find((block, index) => { // 计算当前块具体缺失的属性列表 const missingProps = REQUIRED_PROPS.filter(prop => !Object.hasOwn(block, prop)); if (missingProps.length) { // 可直接拿到缺失属性的明细,不需要额外补排查日志 console.log(`第${index + 1}个块缺失必填属性:${missingProps.join('、')}`); return true; } return false; });
核心优势
- 校验精度更高:用规范的属性存在性判断替代原有的真值判断,不会把属性存在但值为falsy的场景误判,比如块的
id为数字0的场景,原逻辑会误判为无效,新逻辑可以准确识别。 - 可维护性更强:所有需要校验的属性集中在配置数组里,后续要新增校验字段(比如加个
type属性)只需要往数组里加一项就行,不需要在长if判断里堆新的条件表达式。 - 场景适配灵活:需要全量收集无效项时用
filter/forEach遍历,需要快速找首个异常时用find,不需要重复写遍历判断逻辑。
内容的提问来源于stack exchange,提问作者DLateef
相关产品推荐
相关产品推荐

