如何实现带例外规则且不修改原型的JS标题大小写转换方法
解决方案:不修改原型实现自定义标题大小写转换(支持例外规则)
如果严格不修改String原型,可以用工具函数实现;如果想要像.toLowerCase()一样的方法调用便捷性,也可以安全扩展原型(仅在方法不存在时添加,避免覆盖原有逻辑)。两种方案都支持自定义例外词,且保留原有的「次要单词非首尾时小写」规则。
方案一:工具函数(完全不修改原型)
实现代码
// 例外词映射:键为小写单词,值为预设的目标大小写形式 const casingExceptions = new Map(); // 初始化预设例外词 ["cm", "DOE", "ft", "ID", "KC", "mm", "TV", "USA"].forEach(word => { casingExceptions.set(word.toLowerCase(), word); }); // 次要单词列表(非首尾位置时强制小写) const minorWords = new Set([ "a", "an", "and", "as", "at", "but", "by", "for", "from", "in", "into", "near", "nor", "of", "on", "onto", "or", "the", "to", "with" ]); // 核心转换函数 function toTitleCase(str) { if (typeof str !== 'string') return str; return str.replace(/[\w’'-]+/g, (match, index, fullStr) => { const lowerMatch = match.toLowerCase(); // 优先匹配例外词,直接返回预设格式 if (casingExceptions.has(lowerMatch)) { return casingExceptions.get(lowerMatch); } // 判断当前单词是否为字符串的首尾单词 const isFirstWord = index === 0 || /^\s*$/.test(fullStr.slice(0, index)); const isLastWord = index + match.length === fullStr.length || /^\s*$/.test(fullStr.slice(index + match.length)); // 基础标题大小写转换 let processedWord = match.charAt(0).toUpperCase() + match.slice(1).toLowerCase(); // 非首尾的次要单词转为小写 if (!isFirstWord && !isLastWord && minorWords.has(lowerMatch)) { processedWord = processedWord.toLowerCase(); } return processedWord; }); }
使用方式
直接传入字符串调用:
const input = 'THE DOE IN THE USA DOESN’T USE THE UNIT CM.'; const output = toTitleCase(input); console.log(output); // 输出:"The DOE in the USA Doesn’t Use the Unit cm."
补充例外词
后续需要添加新规则时,只需调用:
// 示例:添加"GDP"(全大写)和"kg"(全小写) casingExceptions.set("gdp", "GDP"); casingExceptions.set("kg", "kg");
方案二:安全扩展原型(方法调用形式)
如果想要像原生方法一样直接在字符串实例上调用,且避免覆盖已有方法,可以在仅当toTitleCase不存在时扩展String原型:
实现代码
// 例外词映射 const casingExceptions = new Map(); ["cm", "DOE", "ft", "ID", "KC", "mm", "TV", "USA"].forEach(word => { casingExceptions.set(word.toLowerCase(), word); }); // 次要单词列表 const minorWords = new Set([ "a", "an", "and", "as", "at", "but", "by", "for", "from", "in", "into", "near", "nor", "of", "on", "onto", "or", "the", "to", "with" ]); // 安全扩展原型:仅当方法不存在时添加 if (!String.prototype.toTitleCase) { String.prototype.toTitleCase = function() { return this.replace(/[\w’'-]+/g, (match, index, fullStr) => { const lowerMatch = match.toLowerCase(); if (casingExceptions.has(lowerMatch)) { return casingExceptions.get(lowerMatch); } const isFirstWord = index === 0 || /^\s*$/.test(fullStr.slice(0, index)); const isLastWord = index + match.length === fullStr.length || /^\s*$/.test(fullStr.slice(index + match.length)); let processedWord = match.charAt(0).toUpperCase() + match.slice(1).toLowerCase(); if (!isFirstWord && !isLastWord && minorWords.has(lowerMatch)) { processedWord = processedWord.toLowerCase(); } return processedWord; }); }; }
使用方式
直接在字符串实例上调用:
const input = 'THE DOE IN THE USA DOESN’T USE THE UNIT CM.'; const output = input.toTitleCase(); console.log(output); // 输出:"The DOE in the USA Doesn’t Use the Unit cm."
补充例外词
同样通过casingExceptions.set()添加新规则:
casingExceptions.set("ceo", "CEO"); casingExceptions.set("ml", "ml");
核心逻辑说明
- 例外词处理:用
Map存储小写单词到目标格式的映射,确保不管输入的例外词是全大写、全小写还是混合格式,都能准确替换为预设样式。 - 次要单词规则:通过判断单词在字符串中的位置,仅对非首尾的次要单词强制转为小写。
- 正则兼容性:使用
/[\w’'-]+/g匹配包含撇号、连字符的单词,兼容Doesn’t这类特殊格式的词汇。
内容的提问来源于stack exchange,提问作者Mtullis
相关产品推荐
相关产品推荐

