在 JavaScript 中翻转字符串有多种方法,适配不同场景(如简单场景、兼容 Unicode 字符、性能优先等),以下是最常用的 5 种方式,附详细示例、优缺点和选型建议:
一、经典简洁版:split() + reverse() + join()(ASCII 字符串首选)
这是最常用的极简写法,核心是将字符串转为数组、翻转数组、再转回字符串。
语法:
const reversedStr = str.split('').reverse().join('');
示例:
const str = "Hello World";
const reversed = str.split('').reverse().join('');
console.log(reversed); // 输出:dlroW olleH
原理:
split(''):将字符串拆分为字符数组(["H","e","l","l","o"," ","W","o","r","l","d"]);reverse():翻转数组(["d","l","r","o","W"," ","o","l","l","e","H"]);join(''):将数组拼接回字符串。
注意:
该方法不兼容 Unicode 多字节字符(如中文、emoji 😜),会导致字符错位:
const str = "测试😜";
console.log(str.split('').reverse().join('')); // 输出乱码(😜 被拆分为两个伪字符,翻转后错位)
二、兼容 Unicode 版:[...str] / Array.from() + reverse() + join()(推荐)
解决上述方法的 Unicode 兼容问题,用 ES6 扩展运算符 [...str] 或 Array.from() 正确拆分 Unicode 字符。
示例:
// 方式 1:扩展运算符 [...str]
const str1 = "测试😜";
const reversed1 = [...str1].reverse().join('');
console.log(reversed1); // 输出:😜试测(正确翻转)
// 方式 2:Array.from()(效果一致,更兼容低版本 ES6 环境)
const str2 = "JS 遍历😜";
const reversed2 = Array.from(str2).reverse().join('');
console.log(reversed2); // 输出:😜历遍 SJ(正确翻转)
优势:
完美支持中文、emoji、特殊 Unicode 字符,是现代环境的首选。
三、手动遍历版:for 循环(性能最优)
通过反向遍历字符串,手动拼接字符,性能最高(无数组转换开销),兼容所有环境。
示例:
function reverseStr(str) {
let reversed = '';
// 从最后一个字符反向遍历到第一个
for (let i = str.length - 1; i >= 0; i--) {
reversed += str[i]; // 拼接字符
}
return reversed;
}
// 测试 ASCII 字符串
console.log(reverseStr("Hello")); // 输出:olleH
// 注意:传统 for 循环遍历 Unicode 多字节字符仍会错位,需结合 Array.from
function reverseUnicodeStr(str) {
const chars = Array.from(str); // 正确拆分 Unicode 字符
let reversed = '';
for (let i = chars.length - 1; i >= 0; i--) {
reversed += chars[i];
}
return reversed;
}
console.log(reverseUnicodeStr("测试😜")); // 输出:😜试测(正确)
四、高阶函数版:reduce()(简洁且兼容 Unicode)
利用数组 reduce 方法反向拼接,语法简洁,支持 Unicode 字符。
示例:
const str = "测试😜";
// Array.from 拆分 Unicode 字符,reduce 反向拼接
const reversed = Array.from(str).reduce((acc, char) => char + acc, '');
console.log(reversed); // 输出:😜试测
// 解释:
// 初始值 acc = ''
// 第一步:char = '测' → '测' + '' = '测'
// 第二步:char = '试' → '试' + '测' = '试测'
// 第三步:char = '😜' → '😜' + '试测' = '😜试测'
五、递归版(趣味写法,慎用长字符串)
通过递归逐次截取最后一个字符拼接,适合理解递归逻辑,不建议用于长字符串(易触发栈溢出)。
示例:
function reverseStrRecursive(str) {
// 终止条件:字符串为空或只有一个字符
if (str.length <= 1) return str;
// 递归:截取最后一个字符 + 递归处理剩余部分
return str.slice(-1) + reverseStrRecursive(str.slice(0, -1));
}
console.log(reverseStrRecursive("Hello")); // 输出:olleH
console.log(reverseStrRecursive("测试😜")); // 输出:😜试测(兼容 Unicode)
各方法对比与选型建议
| 方法 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| split+reverse+join | 语法极简、性能较好 | 不兼容 Unicode 多字节字符 | 纯 ASCII 字符串(无中文/emoji) |
| [...str]/Array.from+reverse+join | 兼容 Unicode、语法简洁 | ES6+ 环境 | 所有场景(现代环境首选) |
| for 循环手动拼接 | 性能最优、兼容所有环境 | 语法稍繁琐 | 高性能需求、低版本浏览器 |
| reduce 拼接 | 语法简洁、兼容 Unicode | ES6+ 环境、性能略低于 for 循环 | 现代环境、追求代码简洁 |
| 递归 | 理解递归逻辑、兼容 Unicode | 长字符串易栈溢出、性能差 | 学习递归、短字符串趣味场景 |
关键注意点
- Unicode 兼容:只要字符串包含中文、emoji、特殊符号(如
🍎、𝌆),就必须用[...str]/Array.from()拆分字符,避免split(''); - 性能:
- 短字符串:所有方法差异可忽略,优先选简洁的
[...str].reverse().join(''); - 长字符串(10万+字符):优先选
for循环手动拼接(无数组转换开销);
- 短字符串:所有方法差异可忽略,优先选简洁的
- 空字符串/单字符:所有方法都能正确处理(返回原字符串),无需额外判断。
最终推荐
- 现代环境(ES6+)、通用场景:
[...str].reverse().join('')(简洁+兼容 Unicode); - 低版本浏览器/高性能需求:
for循环手动拼接(结合Array.from处理 Unicode); - 纯 ASCII 字符串:
str.split('').reverse().join('')(极简)。