You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在拼接三个字符串之一时避免代码重复?

简化JavaScript冗余字符串拼接代码

我遇到了以下冗余的代码模式:

// 仅定义一次
const articleComponents = {
    header: "",
    sections: [], // {title: string, content: string}[]
    footer: ""
};

// ...

function appendSuffix(suffix)
{
    if (/* 目标为header */) {
        if (!articleComponents.header.endsWith(" ")) {
            articleComponents.header += " ";
        }
        articleComponents.header += suffix;
    }
    else if (/* 目标为body */) {
        if (!articleComponents.sections[articleComponents.sections.length - 1].content.endsWith(" ")) {
            articleComponents.sections[articleComponents.sections.length - 1].content += " ";
        }
        articleComponents.sections[articleComponents.sections.length - 1].content += suffix;
    }
    else if (/* 目标为footer */) {
        if (!articleComponents.footer.endsWith(" ")) {
            articleComponents.footer += " ";
        }
        articleComponents.footer += suffix;
    }
}

这段代码存在明显冗余,但由于JavaScript字符串的不可变性,直接像C++那样用引用简化有难度。

优化目标

  • 每个条件分支中,目标属性的长表达式仅出现一次
  • 不能修改articleComponents的现有结构,仅允许在appendSuffix内部使用辅助对象或逻辑

C++参考实现

为便于理解,以下是我用C++实现的简化版本:

void appendSuffix(string_view suffix) {
    string &target = /* 目标为header */ ? articleComponents.header
                   : /* 目标为body */   ? articleComponents.back().content
                   : /* 目标为footer */ ? articleComponents.footer
                   : throw ...;

    if (target.back() != ' ') {
        target += ' ';
    }
    target += suffix;
}

JavaScript实现方案

JavaScript中没有值类型的直接引用,但可以通过保存目标属性的所属对象和属性名来间接实现类似逻辑,避免重复书写长表达式:

方案1:条件分支绑定目标对象与属性

function appendSuffix(suffix) {
    let targetObj, targetKey;

    if (/* 目标为header */) {
        targetObj = articleComponents;
        targetKey = 'header';
    } else if (/* 目标为body */) {
        // 注意:确保sections不为空,可根据实际情况添加判断
        targetObj = articleComponents.sections[articleComponents.sections.length - 1];
        targetKey = 'content';
    } else if (/* 目标为footer */) {
        targetObj = articleComponents;
        targetKey = 'footer';
    } else {
        throw new Error('无效的目标类型');
    }

    // 统一处理字符串拼接逻辑
    let currentValue = targetObj[targetKey];
    if (!currentValue.endsWith(' ')) {
        currentValue += ' ';
    }
    targetObj[targetKey] = currentValue + suffix;
}

方案2:三元表达式简化目标绑定

如果想更贴近C++的简洁写法,可以用三元表达式直接返回目标对象和属性名的数组:

function appendSuffix(suffix) {
    // 用立即执行函数处理异常分支
    const [targetObj, targetKey] = 
        /* 目标为header */ ? [articleComponents, 'header'] :
        /* 目标为body */ ? [articleComponents.sections.at(-1), 'content'] : // 使用at(-1)更简洁获取最后一项
        /* 目标为footer */ ? [articleComponents, 'footer'] :
        (() => { throw new Error('无效的目标类型'); })();

    let currentValue = targetObj[targetKey];
    if (!currentValue.endsWith(' ')) {
        currentValue += ' ';
    }
    targetObj[targetKey] = currentValue + suffix;
}

说明

由于JavaScript字符串是不可变值类型,我们无法直接获取其引用修改原变量,但通过绑定目标属性的宿主对象和属性名,可以先读取值、处理后再赋值回原属性,既避免了重复代码,又符合原结构的依赖要求。

内容的提问来源于stack exchange,提问作者Jan Schultke

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 21:45:32