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

发布时间:2026/11/5 18:02:45

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/11/5 3:48:27

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

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

2026/11/5 3:49:51

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

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

2026/11/5 3:51:14

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

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

2026/11/5 16:51:33

EasyU优启通PE维护盘实战指南:制作、启动与核心操作全解析

1. 为什么一个PE维护盘值得单独拿出来聊装系统、修引导、救数据、清病毒,这些活儿但凡干过几次的人都知道,真正决定效率的往往不是你手速多快,而是手边那套PE环境靠不靠谱。EasyU(圈内习惯叫优启通)就是在这个场景下被…

2026/11/5 16:26:13

Rust原来很简单二:所有权系统

Part 2 核心篇 —— 所有权系统 本篇覆盖 第 6 ~ 10 章:所有权、借用与引用、生命周期、字符串与切片、内存模型。 ⚠️ 这是全书最重要的一篇。 把它吃透,Rust 从此“很简单”;跳过它,你会处处碰壁。请慢下来,动手敲每一段代码。 第 6 章 所有权:Rust 的第一性原理 6…

2026/11/5 15:00:49

基于Hadoop+Spark的民宿智能推荐系统设计与实现

1. 项目概述:大数据时代的民宿智能推荐这个毕业设计项目融合了当前大数据领域最主流的技术栈,构建了一个完整的民宿推荐系统解决方案。作为一名长期从事大数据系统开发的工程师,我认为这个选题非常贴合实际应用场景——随着旅游业的复苏和共享…

2026/11/5 14:10:30

ADS122U04IPWR+STM32F427ZI工业级温度测量信号链设计

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/11/5 14:10:30

UART接口24位ADC搭配RS485,解决远距离温度监控难题

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/11/5 14:10:30

UART接口24位ADC搭配PIC18F46K22的RTD与热电偶测温实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/11/5 15:39:06

面向复杂光照与角度的宠物面部识别鲁棒性增强策略

在智慧养宠时代,基于视觉的宠物身份识别技术正逐步从实验室走向家庭应用。然而,与配合度高的人类不同,宠物是典型的“非合作生物识别对象”——它们不会主动配合摄像头调整姿态,更无法控制光照环境。实际应用中,我们常…

2026/11/4 21:04:25

SSM电子书店源码全解析:结构、原理、部署与排错实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/11/5 0:02:07

多智能体协作系统架构设计与实践优化

1. 多智能体协作系统的时代背景2017年Transformer架构的诞生彻底改变了人工智能的发展轨迹。当行业还沉浸在单一大模型带来的性能突破时,Anthropic的研究团队已经将目光投向了更前沿的领域——如何让多个智能体通过协作产生超越单体能力的系统智能。这就像交响乐团中…

2026/11/5 0:02:07

大模型系统性入门实战指南:从原理到部署微调的全链路路线

提到大模型的系统性入门,我先说个结论:这事真不难,难的是资料太散、路线太多,今天这个框架明天那个工具,新人很容易在“收藏夹吃灰”和“教程看到一半放弃”之间反复横跳。市面上关于大模型的内容少说有几十万篇&#…

2026/11/5 0:02:07

鸿蒙文件系统沙箱机制解析与开发实践

1. 鸿蒙文件系统沙箱机制深度解析作为一名从Android转向鸿蒙开发的工程师,我深刻体会到文件系统访问是迁移过程中最先遇到的"拦路虎"。在Android上运行良好的文件读写代码,在鸿蒙真机环境却频频出现文件写入后神秘消失或直接抛出权限拒绝错误的…

2026/11/5 15:39:06

面向复杂光照与角度的宠物面部识别鲁棒性增强策略

在智慧养宠时代,基于视觉的宠物身份识别技术正逐步从实验室走向家庭应用。然而,与配合度高的人类不同,宠物是典型的“非合作生物识别对象”——它们不会主动配合摄像头调整姿态,更无法控制光照环境。实际应用中,我们常…

2026/11/4 21:04:25

SSM电子书店源码全解析:结构、原理、部署与排错实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

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

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

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