如何使用instanceof校验含事件列表的JSON文件并匹配Webinar类
问题根因
JSON本身是纯数据存储格式,反序列化得到的条目是原型指向Object.prototype的普通JS对象,不会携带任何JS类的原型链信息。直接拿这些原始条目去做instanceof Webinar校验时,因为这些对象的原型链上根本不存在Webinar类的prototype,校验结果永远为false,自然会出现判断不生效、没有返回结果的情况。
另外你的Webinar类构造函数存在参数顺序错位的问题:构造函数定义的形参顺序为(title, time, date, webinarTitle, webinarLink),但调用父类构造函数super()时传参顺序为(title, date, time),参数顺序不匹配会导致传入父类的日期、时间字段值错乱,严重时会触发运行时报错。
正确实现流程
- 先做结构匹配判断:遍历JSON条目时,先检查条目是否存在代表网会的
webinar字段,从结构上筛选出符合数据要求的条目 - 手动完成类实例化:把结构匹配到的JSON条目,按照Webinar类的构造函数参数要求,传入构造函数生成真正的Webinar类实例
- 再做instanceof校验:只有经过构造函数生成的实例,才是真正属于Webinar类的对象,此时做instanceof校验才会返回预期结果
- 把校验通过的实例渲染到DOM节点上
修正后的参考代码
首先是调整参数顺序的Webinar类:
class Webinar extends Event { // 统一构造函数形参顺序与super传参顺序 constructor(title, date, time, webinarTitle, webinarLink){ super(title, date, time) this.webinarTitle = webinarTitle this.webinarLink = webinarLink } show() { console.log("This " + this.webinarTitle + " webinar " + "is hosted on " + this.webinarLink) } }
然后是JSON读取、校验、渲染的完整逻辑:
async function renderWebinarEvents() { // 加载本地events.json文件 const response = await fetch('./events.json') const rawEventList = await response.json() const validWebinarList = [] rawEventList.forEach(item => { // 结构层面匹配带webinar字段的条目 if (item.webinar) { // 实例化生成Webinar类对象 const webinarObj = new Webinar( item.title, item.date, item.time, item.webinar.webinarTitle, item.webinar.webinarLink ) // 此时instanceof校验可正常生效 if (webinarObj instanceof Webinar) { validWebinarList.push(webinarObj) } } }) // 渲染结果到DOM const container = document.getElementById('event-root') validWebinarList.forEach(webinar => { const card = document.createElement('div') card.innerHTML = ` <h3>${webinar.title}</h3> <p>举办时间:${webinar.date} ${webinar.time}</p> <p>网会主题:${webinar.webinarTitle}</p> <p>入会链接:${webinar.webinarLink}</p> ` container.appendChild(card) }) } // 页面加载完成后触发渲染 window.addEventListener('DOMContentLoaded', renderWebinarEvents)
关键注意事项
instanceof的校验逻辑是沿着对象的原型链向上查找,匹配对应构造函数的prototype,纯数据对象天生不具备自定义类的原型链,无法直接通过instanceof校验- 不要把“判断字段是否存在”的结构匹配逻辑,和“校验类实例身份”的instanceof逻辑混淆:两者是先后衔接的流程,不能互相替代
- 所有自定义类的构造函数,要保证形参顺序、
super()传参顺序保持一致,避免字段值错位引发的异常
内容的提问来源于stack exchange,提问作者Andrei Bucur
相关产品推荐
相关产品推荐

