JavaScript substr() 方法(长文讲解)
💡一则或许对你有用的小广告
欢迎加入小哈的星球 ,你将获得:专属的项目实战 / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论
- 新项目:《从零手撸:仿小红书(微服务架构)》 正在持续爆肝中,基于
Spring Cloud Alibaba + Spring Boot 3.x + JDK 17...
,点击查看项目介绍 ;演示链接: http://116.62.199.48:7070 ;- 《从零手撸:前后端分离博客项目(全栈开发)》 2 期已完结,演示链接: http://116.62.199.48/ ;
截止目前, 星球 内专栏累计输出 90w+ 字,讲解图 3441+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,权限管理,Spring Cloud Alibaba 微服务等等,已有 3100+ 小伙伴加入学习 ,欢迎点击围观
在 JavaScript 开发中,字符串操作是一项基础且高频的任务。无论是数据解析、表单验证,还是用户界面的动态渲染,开发者常常需要对字符串进行截取、替换或提取特定部分的操作。此时,substr()
方法便成为了一个不可或缺的工具。本文将从基础概念、参数解析、实际案例到常见误区,逐步深入讲解 JavaScript substr() 方法
的核心原理与应用场景,帮助开发者高效掌握这一技能。
一、什么是 substr() 方法?
substr()
是 JavaScript 中用于截取字符串的内置方法。它的主要功能是从指定的起始位置开始,截取一定数量的字符,并返回一个新的字符串。
核心语法:
str.substr(startIndex, length)
startIndex
:必填参数,表示截取的起始索引位置。length
:可选参数,表示截取的字符数量。若省略,则默认截取从startIndex
到字符串末尾的所有字符。
形象比喻:
可以将字符串想象为一条珠链,每个字符是一颗珠子。substr()
的作用类似于用剪刀从指定位置开始剪下一段珠链,startIndex
是起始位置,length
是剪下的珠子数量。
二、参数详解与基础用法
1. startIndex
参数的特殊规则
substr()
的 startIndex
允许传入负数,但其行为与其他方法(如 slice()
)有所不同:
- 正数:从字符串的左侧开始计算位置。例如,
"hello".substr(0, 2)
返回"he"
。 - 负数:从字符串的右侧开始计算位置。例如,
"hello".substr(-3, 2)
返回"el"
(从倒数第三个字符开始,截取 2 个字符)。
示例代码:
const str = "JavaScript";
console.log(str.substr(0, 4)); // 输出 "Java"
console.log(str.substr(4, 3)); // 输出 "Scr"
console.log(str.substr(-3)); // 输出 "ipt"(截取最后 3 个字符)
2. 省略 length
参数时的默认行为
当省略 length
参数时,substr()
会从 startIndex
开始,截取到字符串的末尾。
const greeting = "Hello World!";
console.log(greeting.substr(6)); // 输出 "World!"(从索引 6 开始到结束)
三、常见使用场景与案例分析
1. 提取字符串的前 N 个字符
需求:展示用户输入的文本前 10 个字符,并添加省略号。
function truncateText(text) {
if (text.length > 10) {
return text.substr(0, 10) + "...";
}
return text;
}
console.log(truncateText("Hello JavaScript!")); // 输出 "Hello Jav..."
2. 截取文件扩展名
需求:从文件名中提取扩展名(例如从 "report.pdf"
中提取 "pdf"
)。
function getFileExtension(filename) {
const lastDotIndex = filename.lastIndexOf(".");
return filename.substr(lastDotIndex + 1);
}
console.log(getFileExtension("photo.jpg")); // 输出 "jpg"
3. 处理用户输入的手机号掩码
需求:将手机号的中间四位用星号隐藏(例如 138****1234
)。
function maskPhoneNumber(phone) {
const firstPart = phone.substr(0, 3);
const lastPart = phone.substr(-4);
return firstPart + "****" + lastPart;
}
console.log(maskPhoneNumber("13812345678")); // 输出 "138****5678"
四、与 substring()、slice() 的对比
JavaScript 中有三个类似字符串截取方法:substr()
、substring()
和 slice()
。它们的参数规则和行为存在显著差异,需谨慎选择:
方法 | 参数规则 | 负数处理 |
---|---|---|
substr() | substr(startIndex, length) | 负数表示从右侧开始计数 |
substring() | substring(start, end) (start 和end 均为位置索引) | 负数会被视为 0 |
slice() | slice(start, end) (行为与substring() 相似,但支持负数表示相对位置) | 负数表示从右侧开始计数 |
对比案例:
const str = "JavaScript";
console.log(str.substr(4, 3)); // "Scr"
console.log(str.substring(4, 7)); // "Scr"(与 substr 结果相同)
console.log(str.slice(4, 7)); // "Scr"(与 substr 结果相同)
console.log(str.substr(-3)); // "ipt"(负数有效)
console.log(str.substring(-3)); // "JavaScript"(负数转为 0)
console.log(str.slice(-3)); // "ipt"(负数有效)
五、常见误区与注意事项
1. 负数参数的边界问题
当 startIndex
为负数时,其绝对值不能超过字符串长度,否则会从索引 0 开始截取。例如:
const shortStr = "Hi";
console.log(shortStr.substr(-5)); // 输出 "Hi"(因为 -5 的绝对值超过长度 2)
2. substr()
的不可逆性
substr()
返回的是新字符串的拷贝,不会修改原字符串。若需修改原字符串,需重新赋值:
let text = "Hello";
text = text.substr(0, 3); // 正确:text 变为 "Hel"
3. 与 slice()
的参数差异
substr()
的第二个参数是截取长度,而 slice()
的第二个参数是结束索引。这一差异容易导致混淆,需特别注意:
const str = "JavaScript";
str.substr(4, 3) // 截取 3 个字符 → "Scr"
str.slice(4, 7) // 截取到索引 7(不包含) → "Scr"
六、进阶技巧与最佳实践
1. 结合其他方法处理复杂场景
通过组合 substr()
和其他字符串方法,可以实现更灵活的操作。例如,提取 URL 中的路径部分:
function extractPath(url) {
const protocolEnd = url.indexOf("//") + 2;
const domainEnd = url.indexOf("/", protocolEnd);
return url.substr(domainEnd);
}
console.log(extractPath("https://example.com/api/data")); // 输出 "/api/data"
2. 处理国际化字符(如 emoji)
注意 substr()
是基于字符编码的,而非视觉字符。对于多字节字符(如部分 emoji),需结合 Array.from()
或其他方法进行处理:
const emojiStr = "😊JavaScript";
console.log(emojiStr.substr(0, 2)); // 输出 "😊J"(截取前 2 个字符)
结论
JavaScript substr() 方法
是字符串操作中一个强大且灵活的工具,尤其在需要快速截取固定长度或从右侧起始的场景中表现突出。然而,开发者需注意其与 substring()
和 slice()
的差异,以及参数规则的特殊性。通过结合实际案例和参数对比,本文希望帮助读者建立清晰的使用认知,从而在项目中更高效地运用这一方法。掌握 substr()
并与其他工具合理搭配,将显著提升字符串处理的代码质量和开发效率。