网站首页 > 知识剖析 正文
字符串逆序这件事,说难也难,说简单也简单。前端开发嘛,天天和字符串打交道,处理这种需求也是家常便饭。今天咱们就来聊聊,怎么把一个字符串倒过来写。
最直接的方法,大家都知道,API 一把梭。什么 split、reverse、join,三个组合技,轻轻松松搞定。但是,有些朋友可能就会问了:Array.prototype.reverse.call(s) 直接用这个不香吗?香是香,但……不太行。
为啥?因为 字符串不是数组。reverse 这是数组的原型方法,非数组用不了。你强行 call 上去,浏览器得懵:“哥,咱俩压根不是一类的,别勉强我。” 所以,不能直接拿 reverse.call 来搞字符串。不过咱也别急,办法还是有的。
API 派:三件套,稳
先看最经典的写法:
const reverse = (s) => s.split("").reverse().join("");
reverse("hello"); // => "olleh"
啥意思?一拆解就明白了:
- split(""):把字符串拆成一个个字符的小数组,比如 "hello" 变成 ["h", "e", "l", "l", "o"]。
- reverse():数组反转,["o", "l", "l", "e", "h"]。
- join(""):再把数组拼回字符串 "olleh"。
三个操作,一气呵成,优雅、简洁,这谁看了不说一句专业呢?
但如果你真的就拿 Array.prototype.reverse.call(s) 去用,嘿嘿,它直接报你个错:“s.reverse is not a function”,气不气人?因为 s 是字符串,人家没有 reverse 这个方法,call 也白搭。
所以,想用 reverse,必须得先把字符串变成数组,这也解释了为啥 split 这一步必不可少。
手写派:不靠 API,自力更生
有的朋友可能不屑了:“用 API 多没劲,写代码不就为了秀操作吗?” 那行,来个纯手写版,撸起袖子,咱干!
function reverse(s) {
let r = "";
for (const c of s) {
r = c + r;
}
return r;
}
reverse("hello"); // => "olleh"
看着简单,其实小巧思满满。逐个拿出字符串里的每个字符,每次都插到新字符串的最前面。这不就倒过来了?
要我说,这种写法虽然不复杂,但是真有点“笨办法最可靠”的味道。尤其是当面试官问你:“能不用 API 写个字符串反转吗?” 你要是能当场写出来,立马加分。
不过,这种手写法也有点小问题。如果字符串特别长,比如几万个字符,这种方式就会不断地拼接字符串,性能可能有点拉胯。毕竟,字符串在 JS 里是不可变的,拼接其实是在不停地创建新字符串,换句话说就是在疯狂申请新内存,这样搞效率不高。
双指针派:更高效一点
要说秀操作,其实还有一种写法,稍微高效点——双指针,这可是刷算法题的标配:
function reverse(s) {
const arr = s.split("");
let left = 0, right = arr.length - 1;
while (left < right) {
[arr[left], arr[right]] = [arr[right], arr[left]];
left++;
right--;
}
return arr.join("");
}
reverse("hello"); // => "olleh"
思路特别清晰,左右两边往中间夹,互换位置。和数组反转是一个套路。为什么要先 split 呢?因为咱还是得把字符串变成数组,才能在原地交换元素。
这种方法的优势在哪?内存利用率高,字符串被转成数组以后,在数组内部就地反转,最后再拼回字符串,速度更快,尤其是长字符串更明显。
那reverse.call(s)到底能不能用?
咱绕回最开始的问题,能不能直接用 Array.prototype.reverse.call(s) 来逆序字符串?答案很明确:不能。因为 reverse 是数组专属的,字符串不吃这一套。
如果你非得秀一波骚操作,可以这么写:
Array.prototype.reverse.call(s.split(""));
或者更完整点:
[].reverse.call(s.split(""));
但问题来了:既然都 split 了,干嘛还这么麻烦?直接用 s.split("").reverse().join("") 不香吗?所以这个方法更多是用来秀知识点,不是真正的实用招。
总结一句,字符串反转这种操作,说白了看场合。要简单省事,API 直接干;要秀一波操作,手写法或者双指针上场;要解释原理,别忘了字符串不是数组,不能直接用 reverse。
说到底,开发嘛,灵活点就行,该用 API 就用,别死磕。但底层原理心里有点数,关键时刻不掉链子,才是正经事。
猜你喜欢
- 2025-05-02 JS 写正则表达式,判断是否为手机号
- 2025-05-02 JS 类型检测:谈 typeof 和 instanceof 的缺陷与优化
- 2025-05-02 零起点Python机器学习快速入门-4-3-字符串常用方法
- 2025-05-02 输出、同步和异步(同步和异步输入信号的区别)
- 2025-05-02 最快清除数组空值?分享 1 段优质 JS 代码片段!
- 2025-05-02 JS 克隆对象八种技术,为何少不了 StructuredClone?
- 2025-05-02 C语言字符串操作总结大全(超详细)
- 2025-05-02 推荐一个检测 JS 内存泄漏的神器(js内存泄漏的原因及解决办法)
- 2025-05-02 模拟 Vue 中 JS 动态表达式在模版中被动态解析的实现
- 2025-05-02 解决 JS 对象中继承性问题之方式一:通过原型链继承来解决继承问题
- 最近发表
-
- Zion无代码,小程序授权和解绑,无代码开发的关键
- 韦德二儿子“变”女儿,韦德支持儿子,与魔术师约翰逊经历相同
- 新鞋速报|Swoosh 面世 50 年!Nike Waffle Trainer 2致敬 Nike 的起源
- 李宁韦德之道2低帮版"踏冰" 球鞋曝光
- Zion又壮了!首秀顶翻1.9亿内线!英格拉姆单臂隔扣
- 音乐手游《zion载音》迎更新 钢琴白发少女免费带回家
- AI 应用赚钱工具哪家强?Coze 和 Zion 对比分析
- 韦德12岁次子完成变性手术,心情雀跃身姿妖娆
- 韦德晒全家福,他穿浴袍像中东土豪,二儿子扎雅比尤尼恩还性感
- 每日NBA球星上脚球鞋「5月12日」(近期nba球星上脚球鞋)
- 标签列表
-
- xml (46)
- css animation (57)
- array_slice (60)
- htmlspecialchars (54)
- position: absolute (54)
- datediff函数 (47)
- array_pop (49)
- jsmap (52)
- toggleclass (43)
- console.time (63)
- .sql (41)
- ahref (40)
- js json.parse (59)
- html复选框 (60)
- css 透明 (44)
- css 颜色 (47)
- php replace (41)
- css nth-child (48)
- min-height (40)
- xml schema (44)
- css 最后一个元素 (46)
- location.origin (44)
- table border (49)
- html tr (40)
- video controls (49)