Refine 前端开发中的 JavaScript `String.prototype.substring()` 深度指南:语法、提取模式与 `slice()` 对比

发布时间:2026/9/10 0:20:59

Refine 前端开发中的 JavaScript `String.prototype.substring()` 深度指南:语法、提取模式与 `slice()` 对比 Refine 前端开发中的 JavaScriptString.prototype.substring()深度指南语法、提取模式与slice()对比【免费下载链接】refineA React Framework for building internal tools, admin panels, dashboards B2B apps with unmatched flexibility.项目地址: https://gitcode.com/GitHub_Trending/re/refine导读String.prototype.substring()是 JavaScript 中最常用的字符串提取方法之一在 Refine 这类以数据密集型界面为主的 React 框架项目中无论是解析 URL 查询参数、截断表格文本还是处理包版本信息都离不开对它的精确理解。本文以 documentation/blog/2024-12-31-js-substring.md 为骨架系统讲解substring()的方法签名、四种典型提取模式、startIndex与endIndex的边界细节并结合本仓库源码中的真实调用实例对比substring()、slice()与已废弃的substr()的差异帮助你写出零踩坑的字符串提取代码。什么是 JavaScriptsubstring()substring()是 JavaScriptString类型的原型方法用于提取并保存父字符串的一部分。在提取过程中原始字符串保持不变非破坏性操作目标部分会以一个新字符串返回。String.prototype.substring()特别适合按索引区间从父字符串中生成子串子串可以来自字符串开头、两个索引之间也可以来自字符串尾部。掌握它的关键在于理解两个参数startIndex与endIndex的语义以及零基索引zero-based index对提取结果的影响。substring()方法签名substring()接受两个可选参数startIndex与endIndex。其中startIndex是必需的endIndex可省略省略时提取将进行到字符串末尾。substring(startIndex); substring(startIndex, endIndex);两条边界规则决定了提取结果startIndex处的字符是包含的inclusive即返回的子串包含起始位置字符endIndex处的字符是排除的exclusive即提取结束于endIndex之前的那个字符。仅传startIndex从起始点提取到字符串末尾只传startIndex时得到的是从startIndex一直到父字符串结尾的子串const mnemonic Please, send, cats, monkeys, and, zebras, in, large, cages, make, sure, padlocked.; console.log(mnemonic.substring(14)); // cats, monkeys, and, zebras, in, large, cages, make, sure, padlocked.模式一提取前n个字符之后的尾部由于startIndex使用零基索引前startIndex个字符的最后一个索引恰好是startIndex - 1。又因为startIndex处的字符包含在结果中所以substring(n)返回的正是前n个字符之后的尾部const mnemonic Please, send, cats, monkeys, and, zebras, in, large, cages, make, sure, padlocked.; // 提取前 14 个字符之后的尾部 console.log(mnemonic.substring(14)); // cats, monkeys, and, zebras, in, large, cages, make, sure, padlocked. // 提取前 20 个字符之后的尾部 console.log(mnemonic.substring(20)); // monkeys, and, zebras, in, large, cages, make, sure, padlocked. // 提取前 29 个字符之后的尾部 console.log(mnemonic.substring(29)); // and, zebras, in, large, cages, make, sure, padlocked. // 提取前 72 个字符之后的尾部 console.log(mnemonic.substring(72)); // padlocked.仓库实例这种去掉前 N 个字符的用法在 Refine 源码中很常见。例如 packages/core/src/definitions/table/index.ts 中parseTableParams在处理带?前缀的查询字符串时正是用url.substring(1)去掉第一个?字符后再交给qs.parse解析export const parseTableParams (url: string) { const { currentPage, pageSize, sorters, sorter, filters } qs.parse( url.substring(1), // 移除第一个 ? 字符 { depth: QS_PARSE_DEPTH }, ); // ... };模式二同时传startIndex与endIndex提取两点之间的子串同时传入两个参数时提取的是满足startIndex str endIndex区间的字符结果在endIndex之前结束const mnemonic Please, send, cats, monkeys, and, zebras, in, large, cages, make, sure, padlocked.; console.log(mnemonic.substring(14, 27)); // cats, monkeys模式三提取前n个字符当需要从父字符串开头提取子串时令startIndex为0即可const mnemonic Please, send, cats, monkeys, and, zebras, in, large, cages, make, sure, padlocked.; console.log(mnemonic.substring(0, 27)); // Please, send, cats, monkeys以startIndex 0、endIndex n调用得到的就是父字符串的前n个字符const mnemonic Please, send, cats, monkeys, and, zebras, in, large, cages, make, sure, padlocked.; // 前 12 个字符 console.log(mnemonic.substring(0, 12)); // Please, send // 前 18 个字符 console.log(mnemonic.substring(0, 18)); // Please, send, cats // 前 27 个字符 console.log(mnemonic.substring(0, 27)); // Please, send, cats, monkeys // 前 70 个字符 console.log(mnemonic.substring(0, 70)); // Please, send, cats, monkeys, and, zebras, in, large, cages, make, sure模式四用length - n提取最后n个字符通过把调用者的length用到startIndex上可以提取尾部字符const mnemonic Please, send, cats, monkeys, and, zebras, in, large, cages, make, sure, padlocked.; // 最后 9 个字符 console.log(mnemonic.substring(mnemonic.length - 9)); // padlocked. // 最后 15 个字符 console.log(mnemonic.substring(mnemonic.length - 15)); // sure, padlocked.其原理是mnemonic.length使startIndex恰好落在父字符串末尾之外将startIndex回移n个位置即从尾部第n个字符处开始提取由于未传endIndex提取会持续到字符串结尾因此得到最后n个字符。startIndex与endIndex的边界细节startIndex endIndex时索引会被交换当startIndex大于endIndex时substring()会交换两个索引后再提取const mnemonic Please, send, cats, monkeys, and, zebras, in, large, cages, make, sure, padlocked.; // 等价于 mnemonic.substring(0, 6) console.log(mnemonic.substring(6, 0)); // Please负数startIndex与endIndex会被当作0startIndex或endIndex为负数时对应的值会被置为0const mnemonic Please, send, cats, monkeys, and, zebras, in, large, cages, make, sure, padlocked.; // 等价于 mnemonic.substring(0, 6) console.log(mnemonic.substring(-1, 6)); // Please // 等价于 mnemonic.substring(0, 0) console.log(mnemonic.substring(-1, -6)); // // 等价于 mnemonic.substring(12, 0)进一步交换为 mnemonic.substring(0, 12) console.log(mnemonic.substring(12, -6)); // Please, send最后一次调用中-6先被置为0由于12 0又发生了索引交换最终等价于mnemonic.substring(0, 12)。substring()与其他字符串提取方法的对比slice()与substr()也是字符串提取方法但实现细节差异明显。substring()vsslice()两者提取逻辑几乎一致主要差异如下索引交换startIndex endIndex时substring()会交换索引而slice()不会交换直接返回空字符串表示不存在的字符区间const mnemonic Please, send, cats, monkeys, and, zebras, in, large, cages, make, sure, padlocked.; // 交换为 mnemonic.substring(0, 6) console.log(mnemonic.substring(6, 0)); // Please // 不交换返回空字符串 console.log(mnemonic.slice(6, 0)); // 负数处理当参数为负时slice()会从最后一个字符向前回溯定位索引若交换后startIndex endIndex切片照常工作const mnemonic Please, send, cats, monkeys, and, zebras, in, large, cages, make, sure, padlocked.; // 负数归零并交换为 mnemonic.substring(0, 18) console.log(mnemonic.substring(18, -12)); // Please, send, cats // 不交换-12 从尾部定位索引字符串足够长切片生效 console.log(mnemonic.slice(20, -12)); // monkeys, and, zebras, in, large, cages, make, sure console.log(mnemonic.substring(-12, 18)); // Please, send, cats // 不交换-12 从尾部定位索引但 startIndex endIndex返回空字符串 console.log(mnemonic.slice(-12, 18)); // console.log(mnemonic.substring(-16, -12)); // // 两个参数都从尾部定位索引startIndex endIndex切片生效 console.log(mnemonic.slice(-16, -12)); // suresubstring()vssubstr()substr()也是字符串提取方法但它是遗留legacy方法其第二个参数表示目标子串的长度而不是结束索引const mnemonic Please, send, cats, monkeys, and, zebras, in, large, cages, make, sure, padlocked.; console.log(mnemonic.substring(10, 12)); // nd // 从 startIndex 起取 12 个字符 console.log(mnemonic.substr(10, 12)); // nd, cats, mo此外与slice()类似substr()的负数startIndex也会从最后一个字符向前计数const mnemonic Please, send, cats, monkeys, and, zebras, in, large, cages, make, sure, padlocked.; console.log(mnemonic.substring(-10, 12)); // Please, send // startIndex 从尾部回溯 10 个字符取 10 个字符剩余 2 个字符不足 console.log(mnemonic.substr(-10, 12)); // padlocked.上面substr(-10, 12)只取到 10 个字符因为目标 12 个字符中有 2 个不在末尾 10 个字符之内。仓库实例Refine 源码中slice()被广泛用于需要从尾部取字符或精确截断的场景这正好呼应上述差异——当需要负数索引时slice()才是正确的选择packages/cli/src/components/version-table/index.ts 的ellipsisFromCenter用text.slice(0, Math.floor(fitLength / 2))与text.slice(-Math.ceil(fitLength / 2))从字符串中心截断并拼接省略号左侧用正索引、右侧用负索引这正是slice()独有的能力packages/core/src/definitions/helpers/humanizeString/index.ts 用text.charAt(0).toUpperCase() text.slice(1)实现字符串首字母大写slice(1)等价于substring(1)二者在该场景下行为一致。使用substring()的常见错误误区一忘记传endIndexendIndex是可选的。不传时substring()会从startIndex一直提取到字符串末尾。多数情况下这是合理的但如果本意是提取某个区间却漏掉了endIndex就会得到超出预期的结果const text Hello, World!; console.log(text.substring(7)); // World! console.log(text.substring(7, 12)); // World实践中应先确认是否真的需要endIndex再调用。同时要警惕负数参数的陷阱——substring()把负数当作0而slice()会从尾部回溯const text Hello, World!; console.log(text.substring(-5)); // Hello, World!负数被当作 0 console.log(text.slice(-5)); // orld!建议需要负数索引时直接使用slice()。误区二startIndex endIndex时依赖隐式交换当startIndex大于endIndex时substring()会交换它们slice()则不会而是返回空字符串。不注意这一点极易产生隐蔽 bugconst text Hello, World!; console.log(text.substring(12, 7)); // World索引被交换 console.log(text.slice(12, 7)); // slice 不交换返回空字符串建议只要使用substring()就始终保证startIndex endIndex。常见问题FAQQstartIndex等于endIndex时返回什么A返回空字符串因为endIndex处的字符不被包含const text Hello, World!; console.log(text.substring(5, 5)); // Qsubstring()会修改原始字符串吗A不会。它是非破坏性的只返回新字符串原始字符串保持不变const text Hello, World!; const result text.substring(7); console.log(result); // World! console.log(text); // Hello, World!Q索引超出字符串长度会怎样A索引超过字符串长度时substring()会在字符串末尾停止不会报错const text Hello; console.log(text.substring(2, 10)); // llo console.log(text.substring(10, 20)); // Qsubstring()与slice()到底有什么区别A两者功能相似但有两个关键差异一是startIndex endIndex时substring()会交换索引而slice()不会二是slice()支持负数索引substring()不支持负数一律当作0const text Hello, World!; console.log(text.substring(7, 12)); // World console.log(text.slice(-5)); // orld!Q关于负数索引最常见的误解是什么Asubstring()并不支持负数索引。传入负数startIndex或endIndex时它只会把该值当作0处理。很多人会把这一点与真正支持负数索引的slice()混淆。总结本文围绕String.prototype.substring()完成了从入门到细节的完整演练明确substring()是返回父字符串目标部分的提取方法startIndex为必需参数且其值包含在结果中endIndex标记提取终止位置且其值不包含在结果中通过实例掌握四种提取模式仅传startIndex提取尾部、substring(0, n)提取前n个字符、双索引提取区间子串、length - n提取最后n个字符理解startIndex endIndex时的索引交换行为以及负数参数被当作0的规则对比substring()与slice()、substr()的实现差异slice()不交换索引且支持负数回溯substr()第二参数是长度且为遗留 API结合 Refine 仓库源码如 parseTableParams 中url.substring(1)去掉?、ellipsisFromCenter 中slice的中心截断看到这些方法在生产代码中的真实用法。掌握这些细节后在处理 URL 参数解析、文本截断、版本号拆解等常见字符串任务时你就能准确选择substring()或slice()避免索引交换、负数误用等隐蔽问题。【免费下载链接】refineA React Framework for building internal tools, admin panels, dashboards B2B apps with unmatched flexibility.项目地址: https://gitcode.com/GitHub_Trending/re/refine创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
延伸阅读

更多相关文章

2026/9/10 0:15:59

Helix 3D Toolkit:用代码参数化生成螺旋结构的工具库

简介:Helix 3D Toolkit 是面向 WPF 与 WinRT/Metro 平台的 3D 开发工具包,适合需要在 Windows 应用中集成三维交互界面的开发者,帮助简化 3D 视图、模型容器与三维对象的管理与操作。压缩包共 814 个文件、约 14.36MB,以 C# 源码&…

2026/9/10 0:15:59

科研级相机微弱信号捕捉:制冷降噪与暗电流控制全解析

先说说我的感受。玩天文摄影和科学观测的朋友应该都有过这种体验:目标明明就在视野里,信号就是弱得可怜。行星表面细节、暗淡星云的长曝光、光谱实验里某个只有几十电子增量的特征峰——这些场景下,普通相机的底噪和热噪声会让你怀疑人生。真…

2026/9/10 0:15:58

C#上位机对接HTTP POST JSON接口:实战经验与踩坑记录

简介:实现C# HTTP POST的JSON数据交互,是许多.NET开发者会遇到的典型场景。这套资料面向需要对接Web API、构建客户端通信模块的C#程序员,系统梳理了HttpClient使用、POST请求构建、异步发送与响应读取,以及Json.NET序列化/反序列…

2026/9/10 1:11:04

基于主从博弈的电热综合能源系统动态定价与能量管理Matlab实现

直接说结论:这套“基于主从博弈的电热综合能源系统动态定价与能量管理”项目,我做过完整复现和改造,今天把建模思路、求解细节、Matlab代码结构、还有调试中踩过的坑一次性整理出来。核心就一句话:运营商定电价和热价,…

2026/9/10 1:11:04

Spring Boot多环境配置实战:彻底解决开发与生产环境切换难题

做Java后端的朋友应该都经历过这种场景:本地代码跑得好好的,一提交到测试环境就报数据库连接超时,再一部署到生产环境,Redis地址不对、日志打不出来、文件上传路径找不到。大多数情况下,问题不是代码逻辑写错了&#x…

2026/9/10 1:11:03

Locust高并发压测实战:从脚本设计到瓶颈定位

如果你也经历过那种凌晨两点被监控电话叫醒,打开面板看到CPU打满、数据库连接池耗尽、线上服务一个接一个雪崩的场景,你应该能理解“压力测试”这四个字的分量。系统跑得好不好,不是上线那一刻才确定的,而是取决于你有没有在上线之…

2026/9/10 1:06:03

计算机硬件基础知识全解析:从CPU到电源的选型与排障指南

开头 “计算机基础”这四个字,听起来像是一个应该早就解决了的问题——毕竟我们每天用电脑工作、打游戏、刷视频,似乎离“基础”二字也不远。可实际情况是,我接触过太多能熟练写代码、能把系统玩出花来的朋友,一旦问到“内存频率和…

2026/9/9 13:11:35

超人会飞不算本事:系统稳定依赖清晰规则与边界设计

开头先不绕弯子。“#斯坦李吐槽dc 所以超人是无缘无故会飞的嘛哈哈哈哈哈哈哈锤哥真是技术人才啊!#雷神 #复联”这类调侃式短标题,第一波冲击力在于它把两个宇宙的角色塞进同一个吐槽箱里,但细想一下就能发现,它真正碰到的根本不是…

2026/9/8 7:15:15

超人VS蜘蛛侠:拆解超级IP的影响力与传播方法论

把“蜘蛛侠 vs 超人”放在 CSDN 上聊,可能很多人第一反应是走错片场了。但如果把这两个角色看成“两个持续运营了 80 多年的文化产品”,你会发现,这场比较本质上是两个不同 IP 策略的长期结果对比:超人赢在定义了整个超级英雄题材…

2026/9/9 16:31:09

基于CNN的调制信号识别:MATLAB实现时频图分类实战

简介:本资源是一套面向通信工程与信号处理方向学习者、研究者的深度学习实践方案,聚焦调制信号自动检测与识别这一典型无线通信任务,解决传统方法依赖人工特征、低信噪比下性能下降等痛点。压缩包共12个文件(10.73MB)&…

2026/9/10 0:00:55

目录对比去重实战:用哈希算法精准清理重复文件

我电脑里现在还有一块换了三次机的“数据墓地”硬盘,里面存着2016年以前所有旧笔记本的完整备份。平时不觉得有什么,直到前阵子想把它整理归档,发现同一个安装包、同一批照片、同一份论文草稿,在几个不同的备份目录里反复出现。更…

2026/9/10 0:00:55

Leaflet离线地图完整Demo合集:内网部署与坐标纠偏实战

简介:这是一份面向Web GIS开发者的LeafLet离线地图示例合集,帮助开发者快速掌握离线地图从搭建到交互的完整流程。压缩包共723个文件,大小14.06MB,以319个js脚本、175个html页面和29个css样式文件为主体,配合png/svg图…

2026/9/10 0:00:55

MATLAB读取Rinex 3.02观测文件:多系统GNSS数据解析实战

简介:基于MATLAB开发的Rinex3.02版观测文件(o文件)读取代码包,面向卫星定位导航方向的学习者与研究人员,用于解决新版观测文件的数据解析、历元提取与时间转换问题。压缩包共4个文件,包含两个m脚本、一个19…

2026/9/7 16:23:03

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/7 22:46:00

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/9 10:21:54

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
咨询二维码