You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用原生JavaScript实现对象多约束校验(不依赖类库)

原生JavaScript实现轻量对象校验模式

需求说明

需实现对象校验逻辑,满足以下约束:

  1. 传入参数必须是非null的对象类型(排除数组)
  2. 对象不能是空对象(无任何键值对)
  3. 对象的每个键和值都需为合法数字:排除NaN、undefined、null
  4. 违反任一约束时立即抛出错误

现有代码问题

当前实现存在几处逻辑错误与不完善点:

  • 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 15:10:39