JavaScript 字符串 substr() 已被废弃:为什么会踩坑?替代用法详解
想快速答案?结论是:不要再使用 substr()
。它已被标准标记为弃用,未来存在移除风险;推荐统一使用 slice()
(必要时再用 substring()
)。
下面是详细解释与迁移清单。
那个90%前端还在踩的坑:substr()
,一个早已被浏览器“拉黑”的API!
你有没有经历过这样的场景:一段代码在你的电脑上跑得好好的,一上线就出了岔子?或者,你在维护一坨“上古代码”时,总感觉哪里不对劲,却又说不上来?
小心,你可能踩中了一颗早已被埋下的“地雷”。而这颗雷的名字,很可能就是 substr()
。
没错,就是那个我们用来截取字符串,熟练得像每天吃饭喝水一样的 substr()
。可是一个残酷的事实是:这个API已经被现代浏览器标准给“拉黑”了。它就像一个过期的罐头,虽然暂时吃不坏肚子,但随时可能让你“中毒”。
更惊人的是,据不完全统计,可能还有90%的开发者在项目中无意识地使用它。
一场“家族内斗”:为什么 substr()
被踢出群聊?
要理解 substr()
为何失宠,我们得认识一下它的两位兄弟:slice()
和 substring()
。这三位都干着截取字符串的活儿,但脾气秉性却大不相同。
想象一下,String
是一个大家族,这三兄弟是家族里最擅长切分家产(字符串)的。
slice(起点, 终点)
substring(起点, 终点)
substr(起点, 长度)
发现问题了吗?
老大 slice
和老二 substring
早就商量好了,切分家产的规矩是“从几号位置切到几号位置”,简单明了。
唯独老三 substr
,天生“反骨”,非要自己搞一套:“从几号位置开始,数几个单位再下刀”。
这种不合群的设计,就是它被废弃的根本原因。这就像你开车导航,所有地图都告诉你“从人民广场开到世纪大道”,突然一个导航非要说“从人民广场出发,向东 5 公里”。在快节奏的编码中,这种思维模式的切换极易导致混乱和 bug。
代码不仅是给机器执行的,更是给人读的。这种不一致性,就是程序员世界的“万恶之源”。
王者之选:为什么 slice()
是你的最佳伴侣?
既然 substr()
不推荐用了,那我们该用谁?首选,也是我的唯一推荐:slice()
。
slice()
不仅严格遵守“起点-终点”的约定,它还有一个独门绝技——支持负数索引!
这简直是神来之笔!想取字符串末尾的几个字符?在过去,你可能需要 str.substr(str.length - 4)
,又臭又长。
现在用 slice()
呢?
const str = "你好,梦兽编程!";
// 想从后面取 4 个字?一个负数搞定!
str.slice(-4); // "编程!"
// 从第 4 个字开始,切到倒数第 2 个字
str.slice(3, -1); // "梦兽编程"
看到没?slice()
的负数索引就像给你开了一扇后门,操作起来优雅又高效。它就像一个经验丰富、做事滴水不漏的专业人士,指令清晰,从不让你猜。
那个“小聪明”的兄弟:substring()
substring()
也遵循“起点-终点”规则,但它有点“小聪明”,有时候反而会帮倒忙。
它有两个特点:
- 不认负数: 任何负数参数都会被它当成 0。
- 自动纠错: 如果你的起点比终点还大,比如
substring(10, 4)
,它会悄悄帮你调换成substring(4, 10)
。
听起来很智能?但在严肃的编程世界里,这种“自作主张”往往是危险的。我们更希望代码在出错时能明确地报错,或者返回一个不符合预期的结果让我们快速定位,而不是静悄悄地“修正”它,把问题隐藏得更深。
所以,虽然 substring()
也能用,但 slice()
那种严格、可预测的行为,才是一个成熟工程师的首选。
迁移清单:从 substr()
到 slice()
/ substring()
- 以长度截取末尾 N 个字符:
// before
str.substr(str.length - N, N)
// after
str.slice(-N)
- 从索引 i 起,截取长度 N:
// before
str.substr(i, N)
// after(等价)
str.slice(i, i + N)
- 只给起点(到末尾):
// before
str.substr(i)
// after
str.slice(i)
- 若你必须保证「较小值为起点」的行为(与
substring
一致):
const start = Math.min(a, b)
const end = Math.max(a, b)
str.slice(start, end)
结论:是时候和 substr()
说再见了!
朋友,放弃 substr()
吧。
这不仅仅是跟上技术潮流,更是为了写出更清晰、更健壮、更易于团队协作的代码。在今天,每一次你敲下 substr()
,都相当于在为未来的自己或同事埋下一颗定时炸弹。
从现在开始,拥抱 slice()
,让你的代码告别歧义,走向光明。
下次当你在代码审查中看到有人还在用 substr()
,请把这篇文章甩给他,并告诉他:“兄弟,该升级你的武器库了!”
关注梦兽编程微信公众号,解锁更多黑科技
常见问题(FAQ)
substr()
什么时候被废弃的?还能用吗? 被 TC39 与 WHATWG 标为弃用,短期多数浏览器仍保留,但可能随时下线或在边缘环境失效。- 我项目里大量使用
substr()
,需要立刻全量替换吗? 建议在功能改动或重构时逐步替换,新增代码一律使用slice()
。 slice()
与substring()
该如何选择? 首选slice()
(支持负数、行为可预测);只在必须复用substring
的“自动交换参数”特性时考虑substring()
。