JavaScript在字符串指定位置插入字符的三种实现方法

6 次阅读

字符串处理是 JavaScript 开发中非常常见的操作,例如给手机号增加分隔符、给日期字符串添加连接符、格式化版本号,或者在某个固定位置插入特殊字符。需要注意的是,JavaScript 的字符串是不可变值,不能直接修改原字符串,因此所谓“插入字符”,本质上都是基于原字符串创建一个新的字符串。

下面介绍三种常用的 JavaScript 字符串指定位置插入字符的方法,并分析它们各自的实现方式、适用场景以及使用时需要注意的问题。

一、使用 slice() 方法插入字符

slice() 是实现字符串指定位置插入最直观的方法之一。它可以按照指定位置截取字符串,然后将截取结果与需要插入的字符重新拼接起来。

基本写法如下:

JavaScript
const str = "abcdef";
const index = 3;
const result = str.slice(0, index) + "X" + str.slice(index);

console.log(result);

输出结果:

abcXdef

这里的关键逻辑是:

JavaScript
str.slice(0, index)

获取插入位置之前的字符串:

abc

然后:

JavaScript
str.slice(index)

获取从插入位置开始到结尾的字符串:

def

最后将三部分拼接起来:

JavaScript
"abc" + "X" + "def"

得到:

abcXdef

封装成通用函数

实际项目中,可以将这个操作封装成一个函数:

JavaScript
function insertAt(str, index, value) {
    return str.slice(0, index) + value + str.slice(index);
}

console.log(insertAt("JavaScript", 4, "-"));

结果:

Java-Script

这种写法结构简单,也比较容易理解,非常适合处理普通字符串插入需求。

指定位置插入多个字符

插入内容并不局限于单个字符,也可以是一段字符串:

JavaScript
const str = "HelloWorld";
const result = str.slice(0, 5) + " JavaScript " + str.slice(5);

console.log(result);

输出:

Hello JavaScript World

因此,slice() 方法实际上实现的是“在指定索引位置插入字符串”。

二、使用 substring() 方法插入字符

substring() 与 slice() 的思路类似,同样可以将字符串拆成两部分,然后把新内容放在中间。

示例代码:

JavaScript
const str = "abcdef";
const index = 3;

const result =
    str.substring(0, index) +
    "X" +
    str.substring(index);

console.log(result);

输出:

abcXdef

封装之后可以写成:

JavaScript
function insertAt(str, index, value) {
    return str.substring(0, index) + value + str.substring(index);
}

console.log(insertAt("abcdef", 2, "-"));

输出:

ab-cdef

substring() 和 slice() 有什么区别

两种方法都可以完成字符串插入,但它们对参数的处理存在一些区别。

slice():

JavaScript
"abcdef".slice(2, 5);

结果:

cde

如果传入负数,slice() 会从字符串末尾开始计算:

JavaScript
"abcdef".slice(-2);

结果:

ef

而 substring() 对负数的处理不同:

JavaScript
"abcdef".substring(-2);

相当于:

JavaScript
"abcdef".substring(0);

最终返回:

abcdef

因此,如果项目中可能使用负数索引,slice() 通常更加灵活。

substring() 更适合简单的非负索引场景

如果明确知道插入位置一定是从 0 开始计算的非负索引,使用 substring() 也没有问题。

例如:

JavaScript
function addSeparator(str, index) {
    return str.substring(0, index) + "-" + str.substring(index);
}

console.log(addSeparator("20261002", 4));

输出:

2026-1002

这种方式代码短小,阅读成本较低。

三、使用数组拆分与 join() 方法插入字符

除了直接进行字符串截取和拼接,还可以利用数组操作完成字符串指定位置插入。

核心思路是先将字符串转换成字符数组,然后使用 splice() 在指定位置插入字符,最后通过 join() 重新组合字符串。

示例:

JavaScript
const str = "abcdef";
const chars = str.split("");

chars.splice(3, 0, "X");

const result = chars.join("");

console.log(result);

输出:

abcXdef

这里:

JavaScript
str.split("")

会得到:

JavaScript
["a", "b", "c", "d", "e", "f"]

然后:

JavaScript
chars.splice(3, 0, "X");

表示从索引 3 开始,删除 0 个元素,同时插入 "X"。

数组变成:

JavaScript
["a", "b", "c", "X", "d", "e", "f"]

最后:

JavaScript
chars.join("")

重新组合成:

abcXdef

封装成通用函数

可以将这种方式写成:

JavaScript
function insertAt(str, index, value) {
    const chars = str.split("");
    chars.splice(index, 0, value);
    return chars.join("");
}

console.log(insertAt("JavaScript", 4, "-"));

结果:

Java-Script

这种方法的优点是逻辑比较直观,而且如果后续还需要进行删除、替换、批量插入等数组操作,会比较方便。

四、三种方法的实际对比

三种实现方式虽然最终效果相同,但适用场景有所区别。

方法核心思路优点适用场景
slice()截取两段后拼接简洁、灵活常规字符串插入
substring()截取两段后拼接简单易懂非负索引插入
split() + splice() + join()转数组后操作操作直观、便于扩展需要复杂字符处理

对于单纯的字符串插入操作,通常直接使用 slice() 就足够了:

JavaScript
const result = str.slice(0, index) + value + str.slice(index);

代码短,而且不需要额外创建字符数组。

如果需要对字符串中的字符进行连续修改,例如同时进行删除、插入和调整位置,那么数组方式会更加灵活。

五、处理插入位置超过字符串长度的情况

实际开发中,插入位置不一定总是合法范围。例如:

JavaScript
const str = "abc";
const index = 10;

const result = str.slice(0, index) + "X" + str.slice(index);

console.log(result);

结果是:

abcX

这是因为 slice() 在超出字符串长度时会自动进行边界处理。

如果业务要求插入位置必须位于字符串范围内,可以主动进行判断:

JavaScript
function insertAt(str, index, value) {
    if (index < 0 || index > str.length) {
        throw new RangeError("插入位置超出字符串范围");
    }

    return str.slice(0, index) + value + str.slice(index);
}

console.log(insertAt("abcdef", 3, "-"));

这样可以避免错误的数据进入后续业务流程。

六、在字符串开头和结尾插入字符

指定位置为 0 时,可以直接在字符串开头插入:

JavaScript
const str = "JavaScript";
const result = str.slice(0, 0) + "#" + str.slice(0);

console.log(result);

结果:

#JavaScript

如果索引等于字符串长度,则表示在字符串末尾添加内容:

JavaScript
const str = "JavaScript";
const result = str.slice(0, str.length) + "#" + str.slice(str.length);

console.log(result);

结果:

JavaScript#

当然,如果只是末尾追加内容,直接使用 + 或模板字符串会更加简单:

JavaScript
const result = str + "#";

七、注意 JavaScript 字符串的索引问题

处理字符串指定位置插入时,一个容易被忽略的问题是 JavaScript 的字符串索引并不完全等同于用户看到的“字符数量”。

对于普通英文字符:

JavaScript
const str = "abc";
console.log(str.length);

结果是:

3

但对于某些 Unicode 字符,例如部分 Emoji:

JavaScript
const str = "";
console.log(str.length);

结果可能是:

2

这是因为 JavaScript 字符串底层采用 UTF-16 编码,部分 Unicode 字符会占用两个 UTF-16 代码单元。

例如:

JavaScript
const str = "AB";

console.log(str.length);

结果为:

4

如果直接按照索引:

JavaScript
console.log(str.slice(0, 2));

可能得到不符合用户预期的结果。

如果业务需要按照 Unicode 码点进行处理,可以考虑使用展开运算符:

JavaScript
const chars = [...str];

chars.splice(2, 0, "X");

const result = chars.join("");

console.log(result);

对于需要准确处理 Emoji 等复杂 Unicode 字符的场景,还可以进一步考虑 Array.from() 或 Intl.Segmenter。

八、字符串指定位置插入字符的推荐写法

如果只是解决普通的 JavaScript 字符串插入问题,可以封装一个通用函数:

JavaScript
function insertAt(str, index, value) {
    if (typeof str !== "string") {
        throw new TypeError("str 必须是字符串");
    }

    if (typeof index !== "number" || !Number.isInteger(index)) {
        throw new TypeError("index 必须是整数");
    }

    if (index < 0 || index > str.length) {
        throw new RangeError("index 超出字符串范围");
    }

    return str.slice(0, index) + value + str.slice(index);
}

console.log(insertAt("abcdef", 3, "-"));

输出:

abc-def

这种写法不仅能够完成字符串插入,还对参数进行了基本校验,更适合在实际项目中复用。

如果需要按照“用户看到的字符”进行位置计算,则应该进一步考虑 Unicode 字符、Emoji 和组合字符等情况,而不能简单依赖 String.length。

九、总结

JavaScript 没有提供类似 insert() 的原生字符串方法,但通过字符串截取和拼接,可以很方便地实现指定位置插入字符。

最常见的三种方式分别是:

JavaScript
// slice()
str.slice(0, index) + value + str.slice(index);
JavaScript
// substring()
str.substring(0, index) + value + str.substring(index);
JavaScript
// split() + splice() + join()
const chars = str.split("");
chars.splice(index, 0, value);
const result = chars.join("");

对于大多数普通场景,slice() 方案代码最简洁,也更容易封装和复用。substring() 可以满足简单的非负索引需求,而数组方案适合需要对字符串内容进行更多结构化操作的场景。

实际开发时还需要关注索引越界、空字符串、多字符插入以及 Unicode 字符等问题。根据具体业务选择合适的实现方式,能够让字符串处理代码更加稳定、清晰。