如何用原生JavaScript实现对象多约束校验(不依赖类库)
原生JavaScript实现轻量对象校验模式
需求说明
需实现对象校验逻辑,满足以下约束:
- 传入参数必须是非null的对象类型(排除数组)
- 对象不能是空对象(无任何键值对)
- 对象的每个键和值都需为合法数字:排除NaN、undefined、null
- 违反任一约束时立即抛出错误
现有代码问题
当前实现存在几处逻辑错误与不完善点:
validateObject未排除null(typeof null === 'object'),会导致null被误判为合法对象validateEntries中值的判断逻辑写反(typeof value == 'number'时抛错,与需求相悖),且存在冗余判断(数字类型的键不可能等于空字符串)result函数未闭合,捕获错误后仅打印日志,未终止流程或向上抛出错误
原生JS实现方案
我们可以实现一个可复用的校验器模式,把校验规则抽离成独立模块,完全基于原生JS实现,无需依赖第三方库:
1. 通用工具函数:判断合法数字
封装函数统一判断值是否为有效数字:
function isValidNumber(value) { return typeof value === 'number' && !Number.isNaN(value) && value !== null && value !== undefined; }
2. 对象结构校验
修复对象类型与非空校验逻辑:
function validateObjectStructure(obj) { // 排除null、数组(若需允许数组可移除Array.isArray判断) if (typeof obj !== 'object' || obj === null || Array.isArray(obj)) { throw new Error('参数必须是非数组的对象类型'); } if (Object.keys(obj).length === 0) { throw new Error('对象不能为空'); } }
3. 键值对规则校验
重构键值校验逻辑,确保符合需求:
function validateKeyValuePair(key, value) { // 注意:Object.entries会将对象键转为字符串,需先转数字再校验 const numericKey = Number(key); if (!isValidNumber(numericKey)) { throw new Error(`无效键:${key},必须是合法数字`); } if (!isValidNumber(value)) { throw new Error(`键${key}对应的值无效:${value},必须是合法数字`); } }
4. 整合校验流程
串联所有校验逻辑,确保错误正确抛出:
function validateTargetObject(obj) { // 先校验对象结构合法性 validateObjectStructure(obj); // 遍历所有键值对逐一校验 for (const [key, value] of Object.entries(obj)) { validateKeyValuePair(key, value); } // 所有校验通过返回true return true; }
5. 使用示例
// 测试合法对象 try { const validObj = { 1: 100, 2: 200 }; validateTargetObject(validObj); console.log('校验通过'); } catch (e) { console.error(e.message); } // 测试空对象 try { validateTargetObject({}); } catch (e) { console.error(e.message); // 输出:对象不能为空 } // 测试键为字符串的对象 try { validateTargetObject({ 'foo': 100 }); } catch (e) { console.error(e.message); // 输出:无效键:foo,必须是合法数字 }
可扩展规则模式
若后续需添加更多校验规则(如键的范围、值的范围),可将规则定义为配置对象,实现更灵活的校验:
// 定义校验规则配置 const validationRules = { key: { min: 1, max: 100 }, value: { min: 0, max: 1000 } }; function validateWithRules(key, value, rules) { const numericKey = Number(key); // 校验键的合法性与范围 if (!isValidNumber(numericKey)) throw new Error('键必须是合法数字'); if (numericKey < rules.key.min || numericKey > rules.key.max) { throw new Error(`键必须在${rules.key.min}-${rules.key.max}之间`); } // 校验值的合法性与范围 if (!isValidNumber(value)) throw new Error('值必须是合法数字'); if (value < rules.value.min || value > rules.value.max) { throw new Error(`值必须在${rules.value.min}-${rules.value.max}之间`); } }
这种模式可快速扩展校验规则,同时完全基于原生JS实现,无需引入外部依赖。
内容的提问来源于stack exchange,提问作者Exodus Reed
相关产品推荐
相关产品推荐

