开发Discord单词随机器时遭遇TypeError: Cannot read property 'facts' of undefined错误,求解决方案
解决Discord单词随机器的
Cannot read property 'facts' of undefined错误 嘿,这个错误我做Discord Bot的时候也踩过坑!TypeError: Cannot read property 'facts' of undefined说白了就是你代码里的item变量是undefined,却硬要访问它的facts属性,肯定会报错。咱们一步步拆解问题,给你落地的修复方案:
问题根源在哪里?
主要有两个大概率的原因:
- 文本文件读取方式不对:你用
require('../text.txt')读取文本文件,但Node.js的require默认会把.txt当作JS模块解析,如果你的text.txt不是合法的JSON数组/JS对象数组,gameChanger根本不是你想要的数组结构,甚至可能是空值或者字符串。 gameChanger是空数组:如果解析后的数组长度为0,Math.floor(Math.random() * gameChanger.length)会等于0,但空数组的第0项就是undefined,自然拿不到facts属性。
具体修复步骤
第一步:规范数据文件格式
如果你想让gameChanger是包含facts属性的对象数组,建议把text.txt改成text.json(更符合Node.js模块规范),内容写成标准JSON格式,示例:
[ {"facts": "apple - 苹果,名词,例句:I eat an apple every day."}, {"facts": "banana - 香蕉,名词,例句:Bananas are rich in potassium."}, {"facts": "cat - 猫,名词,例句:My cat likes sleeping on the sofa."} ]
第二步:正确读取数据
如果用JSON文件,直接require即可(注意路径别写错,../表示上一级目录):
// 最好在模块顶部引入,避免每次执行命令都重复读文件 const gameChanger = require('../text.json');
要是你坚持用.txt文件,就用fs模块读取并手动转成数组:
const fs = require('fs'); const path = require('path'); // 在execute函数内读取文件 const filePath = path.join(__dirname, '../text.txt'); const fileContent = fs.readFileSync(filePath, 'utf8'); // 假设txt文件每行是一条facts内容,转成对象数组 const gameChanger = fileContent.trim().split('\n').map(line => ({ facts: line }));
第三步:添加安全检查,避免意外报错
就算数据没问题,也最好加个判断,防止极端情况导致的崩溃:
setInterval(() => { // 先检查数组是否有效 if (!gameChanger || gameChanger.length === 0) { return message.channel.send('糟了,没有可用的单词数据!'); } const item = gameChanger[Math.floor(Math.random() * gameChanger.length)]; // 再检查item和facts属性是否存在 if (item && item.facts) { message.channel.send(item.facts); } else { message.channel.send('拿到了一条无效的单词数据...'); } }, 5 * 1000);
第四步:小优化——去掉重复变量声明
你在execute函数里已经声明过const item,在setInterval里又重复声明了一次,虽然不报错但没必要,直接改成赋值即可。
完整修复后的代码(JSON文件版本)
const Discord = require('discord.js'); // 提前引入数据文件,提升性能 const gameChanger = require('../text.json'); module.exports = { name: 'game', execute(message, args) { // 初始数据检查 if (!gameChanger || gameChanger.length === 0) { return message.channel.send('错误:没有可用的单词数据,请检查text.json文件!'); } // 先发送第一条内容 const firstItem = gameChanger[Math.floor(Math.random() * gameChanger.length)]; if (firstItem && firstItem.facts) { message.channel.send(firstItem.facts); } // 设置定时发送 setInterval(() => { const item = gameChanger[Math.floor(Math.random() * gameChanger.length)]; if (item && item.facts) { message.channel.send(item.facts); } else { message.channel.send('获取到无效的单词数据,请检查数据文件!'); } }, 5 * 1000); } }
内容的提问来源于stack exchange,提问作者Outrage
相关产品推荐
相关产品推荐

