
本文介绍如何用条件表达式与字符串累积逻辑,高效替代 JavaScript 中大量硬编码的 if-else 分支,实现根据多个变量阈值动态构建格式化字符串 j 和 k,兼顾可读性、可维护性与扩展性。
本文介绍如何用条件表达式与字符串累积逻辑,高效替代 javascript 中大量硬编码的 if-else 分支,实现根据多个变量阈值动态构建格式化字符串 `j` 和 `k`,兼顾可读性、可维护性与扩展性。
在实际开发中,面对多组并行条件判断(如 bOct, cOct, dOct, eOct 各自独立与阈值 3 比较),若采用传统 if/else if 链处理所有 2⁴=16 种组合,不仅代码冗长、易出错,且极难维护和扩展。更优解是将逻辑解耦为“逐项判断 + 累积拼接”——每个变量独立决策是否加入 j 或 k,再统一处理格式化(括号包裹、空格分隔、末尾 /w)。
以下为重构后的核心逻辑(已集成进完整 fetch() 函数):
function fetch() {
const pc = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"];
const text1 = document.getElementById("text1");
const text2 = document.getElementById("text2");
// 初始化音符变量(注意:此处应重置,避免多次调用累积)
let b = "", c = "", d = "", e = "";
let f = "", g = "", h = "", i = "";
let j = "", k = "";
// 随机生成音名索引与八度数
const [bPc, cPc, dPc, ePc, fPc, gPc, hPc, iPc] =
Array(8).fill().map(() => Math.floor(Math.random() * pc.length));
const [bOct, cOct, dOct, eOct] =
Array(4).fill().map(() => Math.floor(Math.random() * 6));
// 赋值音符(C, C#, D...)
b += pc[bPc]; c += pc[cPc]; d += pc[dPc]; e += pc[ePc];
f += pc[fPc]; g += pc[gPc]; h += pc[hPc]; i += pc[iPc];
// ✅ 核心优化:逐项条件拼接,替代 16 个 if
j = (bOct > 3) ? j + b + bOct + " " : j;
j = (cOct > 3) ? j + c + cOct + " " : j;
j = (dOct > 3) ? j + d + dOct + " " : j;
j = (eOct > 3) ? j + e + eOct + " " : j;
k = (bOct <blockquote>
<p>⚠️ <strong>关键注意事项</strong> </p>
<ul>
<li>
<strong>变量重置</strong>:原代码中 b, c, j, k 等未在每次 fetch() 调用时清空,会导致多次执行后字符串不断追加。重构中已确保每次调用均从空字符串开始。 </li>
<li>
<strong>空格处理</strong>:使用 trim() 消除首尾空格后再判断是否含空格(即是否需括号),比 indexOf(" ") !== -1 更语义清晰;正则 /\s+\)/g 可稳健处理末尾多个空格。 </li>
<li>
<strong>可扩展性</strong>:若后续新增变量(如 fOct, gOct),只需在 j/k 的条件链中各加一行,无需修改分支结构,彻底摆脱指数级 if 组合爆炸。 </li>
<li>
<strong>性能与可读平衡</strong>:三元运算符链虽略长,但逻辑线性、无嵌套、调试直观;若追求极致简洁,亦可进一步封装为 buildString 工具函数(见下文延伸建议)。</li>
</ul>
</blockquote><p>? <strong>进阶建议:封装为复用函数</strong><br>
当类似逻辑在多处出现时,可抽象为高阶工具函数:</p><pre class="brush:php;toolbar:false;">function buildTargetString(
conditions, // 布尔数组,如 [bOct > 3, cOct > 3, ...]
values, // 字符串数组,如 [b + bOct, c + cOct, ...]
separator = " "
) {
const parts = conditions.map((cond, i) => cond ? values[i] : null).filter(Boolean);
return parts.length === 0
? ""
: parts.length === 1
? parts[0]
: `(${parts.join(separator)})`;
}
// 使用示例:
j = buildTargetString(
[bOct > 3, cOct > 3, dOct > 3, eOct > 3],
[b + bOct, c + cOct, d + dOct, e + eOct]
) || "";
j = j ? j + "/w" : "";
k = buildTargetString(
[bOct <p>这种模式将“条件判断”与“字符串构建”职责分离,大幅提升代码健壮性与测试友好性。最终,你获得的不再是 16 个脆弱的 if,而是一套清晰、可预测、易于演进的动态字符串生成机制。</p>










