使用Dexie.js时对象判断矛盾:已判定为Object却在if条件中触发类型错误
让我们一步步拆解你遇到的问题:
直接错误原因
你代码里的关键错误出在这一行:
Object.keys(dbStatusSettings.keys).length > 0
dbStatusSettings本身就是你从数据库拿到的settings对象,它并没有名为keys的属性——所以dbStatusSettings.keys的值是undefined。当你把undefined传给Object.keys()时,就会触发Cannot convert undefined or null to object这个报错。
为什么你会感到困惑?
你看到console.log(dbStatusSettings instanceof Object)返回true,但紧接着的if条件却报错,是因为JavaScript的逻辑与(&&)是短路求值的:只有第一个条件为true时,才会执行第二个条件。你的console.log只验证了第一个条件的结果,并没有触碰到第二个条件;而进入if判断时,第一个条件通过后,才会执行第二个条件,这时候才触发了错误。
额外的代码优化点
还有一个没必要的写法:
const dbStatusSettings = await db.status.settings
dbStatus是通过await db.status.get(0)获取到的同步对象,它的settings属性是普通对象,不是Promise,完全不需要加await。虽然这不会直接导致当前报错,但如果数据库中找不到id=0的记录(比如populate钩子没执行成功),dbStatus会是null,这行代码会直接抛出Cannot read properties of null (reading 'settings')的错误。
修正后的代码
async checkIfSettingsExist() { const dbStatus = await db.status.get(0); // 先检查数据库记录是否存在 if (!dbStatus) { console.log("未找到status记录"); return; } const dbStatusSettings = dbStatus.settings; console.log(dbStatusSettings instanceof Object); // 修正Object.keys的参数,直接传入settings对象 if (dbStatusSettings instanceof Object && Object.keys(dbStatusSettings).length > 0) { this.$store.commit('status/updateSettings', dbStatusSettings); return; } // 这里可以添加settings为空时的逻辑,比如从服务器获取数据填充 }
总结你的误解
你误以为错误来自dbStatusSettings instanceof Object这个判断,但实际上错误来自后续对dbStatusSettings.keys的错误访问——你混淆了Object.keys()方法和对象的keys属性。Object.keys(obj)是用来获取对象自身可枚举属性名的数组,而不是访问对象的keys属性。
内容的提问来源于stack exchange,提问作者Robert Wildling

