深入浅出:JavaScript 字符串反转的 6 种解法与面试技巧

字符串反转是一个经典的编程面试题,看似简单,却能有效考察候选人的多个方面:

  • API 熟练度:对 JavaScript 内置方法的掌握程度
  • 代码逻辑能力:能否想出多种解法
  • 算法思维:是否理解递归等高级概念

本文将详细介绍 6 种实现字符串反转的方法,从最简洁到最优雅,帮助你全面掌握这道经典面试题。

方法一:ES6 扩展运算符 + reverse() + join()

javascript 复制代码
function reverseStr(str) {
    return [...str].reverse().join('');
}
console.log(reverseStr('abc')); // 输出: 'cba'

解析:

  1. [...str] :使用 ES6 扩展运算符将字符串转换为字符数组
  2. .reverse() :调用数组的 reverse() 方法反转数组
  3. .join('') :将数组拼接回字符串

优点 :代码简洁优雅,可读性强
时间复杂度 :O(n)
空间复杂度:O(n)

方法二:传统 split() 方法

javascript 复制代码
function reverseStr(str) {
    return str.split('').reverse().join('');
}

解析:

  • split('') :传统方法,将字符串按空字符切割成字符数组
  • 后续步骤同方法一

特点:这是最经典的实现方式,与方法一本质相同,只是字符串转数组的方式不同。

方法三:for 循环倒序遍历

javascript 复制代码
function reverseStr(str) {
    let reversed = '';
    for (let i = str.length - 1; i >= 0; i--) {
        reversed += str[i];
    }
    return reversed;
}
console.log(reverseStr('abc')); // 输出: 'cba'

解析:

  • 从字符串末尾开始向前遍历
  • 逐个字符拼接到新字符串

优点 :逻辑清晰,不依赖高阶 API
缺点 :字符串拼接在循环中效率较低(每次拼接都会创建新字符串)
时间复杂度:O(n²)(理论上,但现代 JS 引擎有优化)

方法四:for...of 循环正序遍历

javascript 复制代码
function reverseStr(str) {
    let reversed = '';
    for (let char of str) {
        reversed = char + reversed;
    }
    return reversed;
}
console.log(reverseStr('hello')); // 输出: 'olleh'

解析:

  • 使用 ES6 的 for...of 循环正序遍历字符串
  • 关键技巧 :每次将新字符添加到结果字符串的前面char + reversed

优点 :代码简洁,易于理解
特点:通过改变拼接顺序实现反转,思路巧妙

方法五:递归实现

javascript 复制代码
function reverseStr(str) {
    // 递归退出条件
    if (str === '') {
        return '';
    } else {
        // 递归:反转剩余字符串 + 第一个字符
        return reverseStr(str.substr(1)) + str.charAt(0);
    }
}
console.log(reverseStr('hello')); // 输出: 'olleh'

解析:

核心思想:将大问题分解为小问题

  • 递归逻辑 :reverseStr('hello') = reverseStr('ello') + 'h'
  • 退出条件:当字符串为空时返回空字符串

执行过程(以 'abc' 为例):

bash 复制代码
reverseStr('abc')
  → reverseStr('bc') + 'a'
    → reverseStr('c') + 'b' + 'a'
      → reverseStr('') + 'c' + 'b' + 'a'
        → '' + 'c' + 'b' + 'a'
          → 'cba'

优点 :展示函数式编程思维,面试加分项
缺点 :可能导致栈溢出(字符串过长时)
时间复杂度:O(n²)(substr 每次创建新字符串)

方法六:reduce() 函数式编程

javascript 复制代码
function reverseStr(str) {
    return [...str].reduce((reversed, char) => char + reversed, '');
}
console.log(reverseStr('hello')); // 输出: 'olleh'

解析:

reduce() 是数组的高阶函数,用于将数组"归约"为单一值:

  • acc(accumulator) :累积结果,初始值为 ''
  • char(current) :当前字符
  • 归约逻辑char + reversed 将当前字符添加到结果前面

执行过程

javascript 复制代码
const arr = ['h', 'e', 'l', 'l', 'o'];
reduce 过程:
  '' + 'h' → 'h'
  'h' + 'e' → 'eh'
  'eh' + 'l' → 'leh'
  'leh' + 'l' → 'lleh'
  'lleh' + 'o' → 'olleh'

优点

  • 函数式编程风格
  • 代码简洁且优雅
  • 展示对高阶函数的深刻理解

时间复杂度 :O(n)
空间复杂度:O(n)

🚀扩展知识:reduce 函数详解

由于 reduce 方法较为抽象,这里单独说明:

javascript 复制代码
const arr = [1, 2, 3, 4, 5, 6];
const total = arr.reduce((acc, cur) => {
    console.log(acc, cur);
    return acc + cur;
}, 0); // 初始值
console.log(total); // 21

执行过程

yaml 复制代码
acc: 0,  cur: 1  → 返回 1
acc: 1,  cur: 2  → 返回 3
acc: 3,  cur: 3  → 返回 6
acc: 6,  cur: 4  → 返回 10
acc: 10, cur: 5  → 返回 15
acc: 15, cur: 6  → 返回 21

核心概念

  • acc:累加器,存储上一次的计算结果
  • cur:当前遍历到的数组元素
  • 初始值:第一次调用时 acc 的值

mdn文档

性能对比

方法 代码量 可读性 性能 推荐指数
扩展运算符 + reverse ⭐⭐⭐ ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐ ⭐⭐⭐⭐⭐
for 循环倒序 ⭐⭐ ⭐⭐⭐⭐ ⭐⭐⭐ ⭐⭐⭐
for...of 正序 ⭐⭐⭐ ⭐⭐⭐⭐ ⭐⭐⭐ ⭐⭐⭐⭐
递归 ⭐⭐ ⭐⭐⭐ ⭐⭐ ⭐⭐⭐
reduce ⭐⭐⭐ ⭐⭐⭐⭐ ⭐⭐⭐⭐ ⭐⭐⭐⭐⭐

面试建议

第一步:快速给出基础解法

先写出方法一(扩展运算符 + reverse),展示你对 JavaScript API 的熟练掌握。

javascript 复制代码
function reverseStr(str) {
    return [...str].reverse().join('');
}

第二步:展示多种思路

主动询问面试官:"我还可以用其他方法实现,比如循环、递归或 reduce,您想看哪种?"

第三步:深入讨论

  • 性能分析:讨论各方法的时间/空间复杂度
  • 边界情况:空字符串、特殊字符、Unicode 字符
  • 实际应用:什么场景下选择什么方法

总结

字符串反转虽然简单,但包含了多种编程范式:

  • 命令式编程:for 循环
  • 函数式编程:reduce、递归
  • 现代 JavaScript:扩展运算符、for...of

掌握这些方法不仅能应对面试,更能提升你的编程思维和代码能力。在实际开发中,推荐使用方法一 (扩展运算符)或方法六(reduce),它们简洁、高效且易于维护。

记住:面试不仅是解决问题,更是展示你的思考过程和代码素养。多种解法的掌握会让你在众多候选人中脱颖而出!

欢迎各位大佬在评论区分享其他解法

相关推荐
努力的白熊嗨18 分钟前
大文件 Hash 计算:Web Worker 并行优化的原理与局限性
javascript·算法
hen3y24 分钟前
基于 jscodeshift 构建高效 Codemod 工具指南
前端·javascript
默海笑1 小时前
VUE后台管理系统:定制化、高可用前台样式处理方案
前端·javascript·vue.js
9号达人1 小时前
@NotBlank 不生效报错 No validator could be found:Hibernate Validator 版本匹配指北
后端·面试·程序员
踏浪无痕1 小时前
6张表、14步业务逻辑,Mall订单事务凭什么比你的3步事务还稳?
spring boot·spring·面试
Y***K4341 小时前
TypeScript模块解析
前端·javascript·typescript
草莓熊Lotso1 小时前
Git 本地操作进阶:版本回退、撤销修改与文件删除全攻略
java·javascript·c++·人工智能·git·python·网络协议
想看一次满天星1 小时前
阿里140-语雀逆向分析
javascript·爬虫·python·语雀·阿里140
鹏多多2 小时前
HTML的Video从基础使用到高级实战+兼容的完全指南
前端·javascript·vue.js