Discord.js角色列表命令发送[object Object]无报错问题排查
解决Discord.js角色列表命令显示[object Object]的问题
嘿,我之前开发Discord机器人时也踩过这个坑!你看到的[object Object]本质是因为你直接把Role对象塞进了Embed描述或者字符串拼接里,JavaScript没法直接把对象转换成人类可读的内容,就会默认输出这个占位符。控制台没报错是因为代码逻辑本身没语法错误,只是处理对象的方式不对而已。
核心问题分析
你用message.guild.roles.cache.filter(c => c.name.startsWith('A'))筛选出来的是一个包含Role对象的集合,每个元素都是Discord.js封装的Role实例,不是字符串。当你直接把这个集合或者数组拼接成字符串时,JS会把每个对象转换成默认的字符串表示——也就是[object Object]。
具体解决方案
你需要把每个Role对象转换成可显示的字符串格式,常见的几种方式如下:
1. 转换为角色提及(最友好,用户点击能跳转角色)
直接调用Role对象的toString()方法,它会返回角色的提及格式(比如<@&123456789>):
// 筛选角色 const filteredRoles = message.guild.roles.cache.filter(role => role.name.startsWith('A')); // 把每个角色转成提及字符串,再用换行拼接 const roleList = filteredRoles.map(role => role.toString()).join('\n'); // 发送Embed const embed = new Discord.MessageEmbed() // 如果是Discord.js v14+,请用EmbedBuilder .setTitle("以A开头的角色列表") .setDescription(roleList || "没有找到名称以A开头的角色"); message.channel.send({ embeds: [embed] });
2. 显示角色名称+ID(适合需要查看ID的场景)
如果需要同时展示角色名称和ID,可以手动拼接:
const roleList = filteredRoles.map(role => `${role.name} (ID: ${role.id})`).join('\n');
3. 仅显示角色名称
如果只需要角色名称,直接提取name属性即可:
const roleList = filteredRoles.map(role => role.name).join('\n');
分块处理的修正方案
如果角色数量太多需要分块发送,同样要先把Role对象转成字符串数组再分块,而不是直接分块对象数组:
const filteredRoles = message.guild.roles.cache.filter(role => role.name.startsWith('A')); const roleStrings = filteredRoles.map(role => role.toString()); // 先转成字符串数组 // 每10个角色分一块(可根据需求调整数量) const chunks = []; for (let i = 0; i < roleStrings.length; i += 10) { chunks.push(roleStrings.slice(i, i + 10).join('\n')); } // 逐块发送Embed chunks.forEach((chunk, index) => { const embed = new Discord.MessageEmbed() .setTitle(`以A开头的角色 - 第${index + 1}/${chunks.length}页`) .setDescription(chunk || "没有匹配的角色"); message.channel.send({ embeds: [embed] }); });
额外注意事项
- 如果你用的是Discord.js v14及以上版本,
MessageEmbed已经被替换成EmbedBuilder,需要从discord.js导入:const { EmbedBuilder } = require('discord.js'); - 确保机器人有发送Embed的权限,不过控制台没报错的话大概率不是这个问题
- 记得处理空结果的情况,避免Embed描述为空显得奇怪
内容的提问来源于stack exchange,提问作者TalentYT
相关产品推荐
相关产品推荐

