颜色对象取值与输出异常:Red无色、Orange显示红色等问题
颜色显示错位问题排查与修复
问题说明
代码目标是读取colors对象中的颜色名称,并用对应十六进制值的ANSI颜色显示该名称(例如Red键对应红色十六进制值,应显示红色的Red文本),但实际输出出现错位:Red文本无颜色,Orange文本显示为红色,后续颜色均存在类似错位情况。

问题代码
const colors = { Red: 0xff0000, Orange: 0xffa500, Yellow: 0xffff00, Green: 0x008000, Blue: 0x0000ff, Indigo: 0x4b0082, Violet: 0xee82ee, Purple: 0x8c03fc } function ColorNameError(prefix, ...message) { Error.call(this); this.message = `[${prefix}]: ${message.join(" ")}`; this.name = "ColorNameError"; if (Error.captureStackTrace) { Error.captureStackTrace(this, ColorNameError); } } ColorNameError.prototype = Object.create(Error.prototype); function colorNames(colors) { if (typeof colors === "undefined") { throw new ColorNameError("NoObjectProvided", "No colors object provided."); } if (typeof colors !== "object") { throw new ColorNameError( "TypeError", ` Expected colors to be an "object" but got "${typeof colors}" instead.` ); } var colorNames = Object.keys(colors); var formattedColors = ""; var responseTime = new Date(); for (var i = 0; i < colorNames.length; i++) { var colorName = colorNames[i]; var colorValue = colors[colorName]; var ansiColor = hexToAnsi(colorValue); formattedColors += `\x1b[1m${colorName}\x1b[0m ${ansiColor}${ansiColor}\n`; } var totalColors = colorNames.length; var elapsedTime = new Date() - responseTime; formattedColors += `\u001b[1mTotal Colors: \u001b[36m${totalColors}\u001b[0m\n\u001b[1mResponse Time: \u001b[33m${elapsedTime}ms\u001b[0m`; return formattedColors; } /** * * @param {HexValueInput} hexValue * @returns {ansiCode} ansiCode */ function hexToAnsi(hexValue) { var hexString = hexValue.toString(16).padStart(6, "0"); var r = parseInt(hexString.substring(0, 2), 16); var g = parseInt(hexString.substring(2, 4), 16); var b = parseInt(hexString.substring(4, 6), 16); var ansiColorCode = 16 + 36 * Math.round((r / 255) * 5) + 6 * Math.round((g / 255) * 5) + Math.round((b / 255) * 5); return `\u001b[38;5;${ansiColorCode}m`; }
问题原因
循环中的字符串拼接逻辑错误:先输出加粗并重置格式的颜色名称,再重复添加ANSI颜色代码,导致颜色代码作用到了下一行的文本上,从而出现错位。
错误代码行:
formattedColors += `\x1b[1m${colorName}\x1b[0m ${ansiColor}${ansiColor}\n`;
修复方案
将颜色名称用对应ANSI颜色代码包裹,确保颜色直接作用于当前行的名称文本:
formattedColors += `${ansiColor}\x1b[1m${colorName}\x1b[0m\n`;
修复后完整代码
const colors = { Red: 0xff0000, Orange: 0xffa500, Yellow: 0xffff00, Green: 0x008000, Blue: 0x0000ff, Indigo: 0x4b0082, Violet: 0xee82ee, Purple: 0x8c03fc } function ColorNameError(prefix, ...message) { Error.call(this); this.message = `[${prefix}]: ${message.join(" ")}`; this.name = "ColorNameError"; if (Error.captureStackTrace) { Error.captureStackTrace(this, ColorNameError); } } ColorNameError.prototype = Object.create(Error.prototype); function colorNames(colors) { if (typeof colors === "undefined") { throw new ColorNameError("NoObjectProvided", "No colors object provided."); } if (typeof colors !== "object") { throw new ColorNameError( "TypeError", ` Expected colors to be an "object" but got "${typeof colors}" instead.` ); } var colorNames = Object.keys(colors); var formattedColors = ""; var responseTime = new Date(); for (var i = 0; i < colorNames.length; i++) { var colorName = colorNames[i]; var colorValue = colors[colorName]; var ansiColor = hexToAnsi(colorValue); // 修复后的拼接逻辑 formattedColors += `${ansiColor}\x1b[1m${colorName}\x1b[0m\n`; } var totalColors = colorNames.length; var elapsedTime = new Date() - responseTime; formattedColors += `\u001b[1mTotal Colors: \u001b[36m${totalColors}\u001b[0m\n\u001b[1mResponse Time: \u001b[33m${elapsedTime}ms\u001b[0m`; return formattedColors; } /** * * @param {HexValueInput} hexValue * @returns {ansiCode} ansiCode */ function hexToAnsi(hexValue) { var hexString = hexValue.toString(16).padStart(6, "0"); var r = parseInt(hexString.substring(0, 2), 16); var g = parseInt(hexString.substring(2, 4), 16); var b = parseInt(hexString.substring(4, 6), 16); var ansiColorCode = 16 + 36 * Math.round((r / 255) * 5) + 6 * Math.round((g / 255) * 5) + Math.round((b / 255) * 5); return `\u001b[38;5;${ansiColorCode}m`; }
内容的提问来源于stack exchange,提问作者Mohtasim Alam Sohom
相关产品推荐
相关产品推荐

