字符串处理是 JavaScript 开发中非常常见的操作,例如给手机号增加分隔符、给日期字符串添加连接符、格式化版本号,或者在某个固定位置插入特殊字符。需要注意的是,JavaScript 的字符串是不可变值,不能直接修改原字符串,因此所谓“插入字符”,本质上都是基于原字符串创建一个新的字符串。
下面介绍三种常用的 JavaScript 字符串指定位置插入字符的方法,并分析它们各自的实现方式、适用场景以及使用时需要注意的问题。
一、使用 slice() 方法插入字符
slice() 是实现字符串指定位置插入最直观的方法之一。它可以按照指定位置截取字符串,然后将截取结果与需要插入的字符重新拼接起来。
基本写法如下:
JavaScriptconst str = "abcdef"; const index = 3; const result = str.slice(0, index) + "X" + str.slice(index); console.log(result);
输出结果:
abcXdef
这里的关键逻辑是:
JavaScriptstr.slice(0, index)
获取插入位置之前的字符串:
abc
然后:
JavaScriptstr.slice(index)
获取从插入位置开始到结尾的字符串:
def
最后将三部分拼接起来:
JavaScript"abc" + "X" + "def"
得到:
abcXdef
封装成通用函数
实际项目中,可以将这个操作封装成一个函数:
JavaScriptfunction insertAt(str, index, value) { return str.slice(0, index) + value + str.slice(index); } console.log(insertAt("JavaScript", 4, "-"));
结果:
Java-Script
这种写法结构简单,也比较容易理解,非常适合处理普通字符串插入需求。
指定位置插入多个字符
插入内容并不局限于单个字符,也可以是一段字符串:
JavaScriptconst str = "HelloWorld"; const result = str.slice(0, 5) + " JavaScript " + str.slice(5); console.log(result);
输出:
Hello JavaScript World
因此,slice() 方法实际上实现的是“在指定索引位置插入字符串”。
二、使用 substring() 方法插入字符
substring() 与 slice() 的思路类似,同样可以将字符串拆成两部分,然后把新内容放在中间。
示例代码:
JavaScriptconst str = "abcdef"; const index = 3; const result = str.substring(0, index) + "X" + str.substring(index); console.log(result);
输出:
abcXdef
封装之后可以写成:
JavaScriptfunction 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() 也没有问题。
例如:
JavaScriptfunction addSeparator(str, index) { return str.substring(0, index) + "-" + str.substring(index); } console.log(addSeparator("20261002", 4));
输出:
2026-1002
这种方式代码短小,阅读成本较低。
三、使用数组拆分与 join() 方法插入字符
除了直接进行字符串截取和拼接,还可以利用数组操作完成字符串指定位置插入。
核心思路是先将字符串转换成字符数组,然后使用 splice() 在指定位置插入字符,最后通过 join() 重新组合字符串。
示例:
JavaScriptconst str = "abcdef"; const chars = str.split(""); chars.splice(3, 0, "X"); const result = chars.join(""); console.log(result);
输出:
abcXdef
这里:
JavaScriptstr.split("")
会得到:
JavaScript["a", "b", "c", "d", "e", "f"]
然后:
JavaScriptchars.splice(3, 0, "X");
表示从索引 3 开始,删除 0 个元素,同时插入 "X"。
数组变成:
JavaScript["a", "b", "c", "X", "d", "e", "f"]
最后:
JavaScriptchars.join("")
重新组合成:
abcXdef
封装成通用函数
可以将这种方式写成:
JavaScriptfunction 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() 就足够了:
JavaScriptconst result = str.slice(0, index) + value + str.slice(index);
代码短,而且不需要额外创建字符数组。
如果需要对字符串中的字符进行连续修改,例如同时进行删除、插入和调整位置,那么数组方式会更加灵活。
五、处理插入位置超过字符串长度的情况
实际开发中,插入位置不一定总是合法范围。例如:
JavaScriptconst str = "abc"; const index = 10; const result = str.slice(0, index) + "X" + str.slice(index); console.log(result);
结果是:
abcX
这是因为 slice() 在超出字符串长度时会自动进行边界处理。
如果业务要求插入位置必须位于字符串范围内,可以主动进行判断:
JavaScriptfunction 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 时,可以直接在字符串开头插入:
JavaScriptconst str = "JavaScript"; const result = str.slice(0, 0) + "#" + str.slice(0); console.log(result);
结果:
#JavaScript
如果索引等于字符串长度,则表示在字符串末尾添加内容:
JavaScriptconst str = "JavaScript"; const result = str.slice(0, str.length) + "#" + str.slice(str.length); console.log(result);
结果:
JavaScript#
当然,如果只是末尾追加内容,直接使用 + 或模板字符串会更加简单:
JavaScriptconst result = str + "#";
七、注意 JavaScript 字符串的索引问题
处理字符串指定位置插入时,一个容易被忽略的问题是 JavaScript 的字符串索引并不完全等同于用户看到的“字符数量”。
对于普通英文字符:
JavaScriptconst str = "abc"; console.log(str.length);
结果是:
3
但对于某些 Unicode 字符,例如部分 Emoji:
JavaScriptconst str = ""; console.log(str.length);
结果可能是:
2
这是因为 JavaScript 字符串底层采用 UTF-16 编码,部分 Unicode 字符会占用两个 UTF-16 代码单元。
例如:
JavaScriptconst str = "AB"; console.log(str.length);
结果为:
4
如果直接按照索引:
JavaScriptconsole.log(str.slice(0, 2));
可能得到不符合用户预期的结果。
如果业务需要按照 Unicode 码点进行处理,可以考虑使用展开运算符:
JavaScriptconst chars = [...str]; chars.splice(2, 0, "X"); const result = chars.join(""); console.log(result);
对于需要准确处理 Emoji 等复杂 Unicode 字符的场景,还可以进一步考虑 Array.from() 或 Intl.Segmenter。
八、字符串指定位置插入字符的推荐写法
如果只是解决普通的 JavaScript 字符串插入问题,可以封装一个通用函数:
JavaScriptfunction 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 字符等问题。根据具体业务选择合适的实现方式,能够让字符串处理代码更加稳定、清晰。