JS中如何校验构造函数调用时已传入全部必要参数?
方案1:构造函数内置必填校验(兜底防线)
直接在每个类的构造函数入口做参数校验,只要调用方传入非法参数就直接抛出明确错误,不管是通过addEntity调用还是直接new实例都能拦截问题。
修改后的类代码示例:
class Entity { constructor(e) { // 前置校验 if (!e || e.x === undefined || e.y === undefined) { throw new Error('Entity 构造参数非法:必须传入包含 x、y 数值属性的对象') } this.x = e.x; this.y = e.y; this.vY = this.vX = 0; this.aX = this.aY = 0; } } class Circle extends Entity { constructor(x, y, r, color) { // 入参校验放在super之前,提前拦截错误 if ([x, y, r, color].includes(undefined)) { const missing = ['x','y','r','color'].filter((k, idx) => [x,y,r,color][idx] === undefined).join('、') throw new Error(`Circle 构造参数缺失:必填参数 ${missing} 不能为 undefined`) } super({"x":x,"y":y}); this.r = r; this.color = color; } }
这种方式的好处是校验逻辑和类定义绑定,后续新增实体类型只要在自己的构造函数里加校验即可,不会和其他逻辑耦合。
方案2:可扩展的addEntity前置校验(提前拦截)
避免用switch-case硬编码实体类型,改用配置表统一管理所有实体的元信息,新增类型只需要修改配置表,不需要调整addEntity的核心逻辑。
第一步:定义实体配置表
// 所有实体类型的配置集中管理,新增类型只需要加一行配置 const ENTITY_META = { circle: { cls: Circle, requiredFields: ['x', 'y', 'r', 'color'] }, // 后续新增矩形示例 // rectangle: { // cls: Rectangle, // requiredFields: ['x', 'y', 'width', 'height', 'color'] // } }
第二步:封装通用校验工具
function validateFields(input, requiredFields, type) { const missingFields = requiredFields.filter(field => input[field] === undefined) if (missingFields.length) { throw new Error(`创建${type}实体失败:缺少必填字段 ${missingFields.join('、')}`) } }
第三步:重写addEntity逻辑
addEntity(e) { try { // 先校验type合法性 if (!e.type || !ENTITY_META[e.type]) { throw new Error(`非法实体类型:${e.type}`) } const meta = ENTITY_META[e.type] // 校验必填字段 validateFields(e, meta.requiredFields, e.type) // 按对应构造函数生成实例 const instance = new meta.cls(e.x, e.y, e.r, e.color) this.entities.push(instance) } catch (err) { console.error(err) } }
两种方案可以同时使用:addEntity的前置校验可以提前在实例化前发现参数问题,构造函数的校验作为兜底,防止其他地方直接调用构造函数时传入非法参数。
内容的提问来源于stack exchange,提问作者Ethan Leyden
相关产品推荐
相关产品推荐

