资讯动态

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

发布时间:2026/9/10 0:20:59 来源:尧图企业网站定制
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),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价