可用repeat()和padend()快速构建文本进度条:先按比例计算填充数,用repeat()生成已填充字符,再用repeat()补未填充字符,封装函数支持自定义参数。

可以用 repeat() 生成重复字符,再用 padStart() 控制总长度,快速构建简洁、可读性强的文本进度条。
明确进度条的基本结构
一个典型的文本进度条由三部分组成:已填充部分(如 █)、未填充部分(如 ░),以及固定总长度(比如 20 个字符)。关键不是画图,而是用字符串操作把“完成比例”映射为对应数量的填充字符。
- 假设总长为
total = 20 - 当前进度为
percent = 0.65(即 65%) - 则已填充字符数应为
Math.floor(total * percent),即13
用 repeat() 生成已填充段
repeat() 能根据数值重复指定字符。它比循环拼接更简洁,也避免了数组 join 的开销。
-
'█'.repeat(13)→'█████████████' - 注意:传入非整数会自动取整(
repeat(2.7)等价于repeat(2)),所以建议显式用Math.floor或Math.round控制精度
用 padStart() 补齐总长度并统一格式
padStart(total, '░') 会确保字符串至少有 total 长度,不足时在左侧补上 '░'。但这里我们希望“已填充段”在左、“未填充段”在右,所以实际是让已填充段 padEnd 更自然——不过 padStart 可用于另一种思路:先构造全空进度条,再用 slice 和 repeat 替换前缀。
更直接的做法是:
- 先生成已填充部分:
'█'.repeat(13) - 再补未填充部分:
'░'.repeat(20 - 13) - 合并:
'█'.repeat(13) + '░'.repeat(7)
但若想统一用 padStart 风格(例如动态替换模板),也可这样写:
const bar = '█'.repeat(Math.floor(20 * 0.65)).padEnd(20, '░');
这里 padEnd 更贴切;若坚持用 padStart,可反向构造:
const emptyBar = '░'.repeat(20);<br>const filled = '█'.repeat(Math.floor(20 * 0.65));<br>const bar = (filled + emptyBar).slice(0, 20); // 截取前20位
封装成可复用函数
把逻辑收拢,支持自定义字符、长度和精度:
function renderBar(percent, options = {}) {<br> const { total = 20, full = '█', empty = '░', round = Math.floor } = options;<br> const filledCount = Math.max(0, Math.min(total, round(percent * total)));<br> return full.repeat(filledCount) + empty.repeat(total - filledCount);<br>}<br><br>// 使用示例<br>console.log(`[${renderBar(0.4)}]`); // [████████ ]<br>console.log(`[${renderBar(0.95, { full: '■', empty: '□', total: 10 })}]`); // [■■■■■■■■■□]
这个函数不依赖 DOM,适合 CLI 输出、日志可视化或服务端渲染场景。










