JS翻转字符串

47 阅读4分钟

在 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

原理:

  1. split(''):将字符串拆分为字符数组(["H","e","l","l","o"," ","W","o","r","l","d"]);
  2. reverse():翻转数组(["d","l","r","o","W"," ","o","l","l","e","H"]);
  3. 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 拼接语法简洁、兼容 UnicodeES6+ 环境、性能略低于 for 循环现代环境、追求代码简洁
递归理解递归逻辑、兼容 Unicode长字符串易栈溢出、性能差学习递归、短字符串趣味场景

关键注意点

  1. Unicode 兼容:只要字符串包含中文、emoji、特殊符号(如 🍎𝌆),就必须用 [...str]/Array.from() 拆分字符,避免 split('')
  2. 性能
    • 短字符串:所有方法差异可忽略,优先选简洁的 [...str].reverse().join('')
    • 长字符串(10万+字符):优先选 for 循环手动拼接(无数组转换开销);
  3. 空字符串/单字符:所有方法都能正确处理(返回原字符串),无需额外判断。

最终推荐

  • 现代环境(ES6+)、通用场景:[...str].reverse().join('')(简洁+兼容 Unicode);
  • 低版本浏览器/高性能需求:for 循环手动拼接(结合 Array.from 处理 Unicode);
  • 纯 ASCII 字符串:str.split('').reverse().join('')(极简)。