如何获取字母大小写转换方法(toLocaleLowerCase、toLocaleUpperCase)对应的supportedLocalesOf等效方案?
这个问题确实戳中了一个小痛点——toLocaleLowerCase和toLocaleUpperCase直接挂在字符串原型上,不像Intl命名空间下的API(比如Intl.PluralRules、Intl.Segmenter)自带supportedLocalesOf工具方法,想直接检测某个locale是否被它们支持,确实没那么直接。
首先得明确:目前ECMAScript标准里并没有为这两个大小写转换方法提供官方的supportedLocalesOf等效实现。这是因为它们的locale支持逻辑是和JS引擎底层的国际化实现深度绑定的,没有单独抽成独立的Intl类。
不过我们有几个实用的替代方案,完全不需要提前了解目标locale的特殊大小写规则:
方案一:借助Intl.Collator间接判断
大小写转换的locale数据和排序(Collator)的locale数据,在绝大多数现代JS引擎里是共享的——比如V8、SpiderMonkey这些主流引擎,都依赖ICU(Unicode国际化组件)提供底层数据,支持排序的locale几乎肯定支持对应的大小写转换规则。
我们可以写一个简单的工具函数:
function isLocaleSupportedForCaseConversion(locale) { return Intl.Collator.supportedLocalesOf(locale).length > 0; } // 测试示例 console.log(isLocaleSupportedForCaseConversion('tr')); // true console.log(isLocaleSupportedForCaseConversion('yue')); // true console.log(isLocaleSupportedForCaseConversion('hyw')); // 取决于引擎,多数情况返回false
这个方法的优点是简单高效,缺点是理论上存在“支持排序但不支持大小写转换”的极端情况,但实际开发中几乎遇不到。
方案二:通用无预设检测函数
如果想要更严谨、不依赖其他Intl API的方法,可以写一个通用检测逻辑,核心思路是:如果引擎支持某个locale的大小写规则,那么至少存在部分字符,在该locale下的转换结果和默认locale不同。我们用两个典型的测试字符覆盖场景:
function supportsLocaleForCaseConversion(locale) { // 选两个在不同locale下转换结果差异明显的字符 const testChars = ['i', 'ß']; // 获取默认locale下的转换结果 const defaultResults = { upper: testChars.map(c => c.toLocaleUpperCase()), lower: testChars.map(c => c.toLocaleLowerCase()) }; // 获取目标locale下的转换结果 const localeResults = { upper: testChars.map(c => c.toLocaleUpperCase(locale)), lower: testChars.map(c => c.toLocaleLowerCase(locale)) }; // 对比结果,只要有一个不同就说明支持该locale for (let i = 0; i < testChars.length; i++) { if (localeResults.upper[i] !== defaultResults.upper[i] || localeResults.lower[i] !== defaultResults.lower[i]) { return true; } } // 如果所有测试字符的转换结果都和默认一致,说明要么该locale规则和默认相同,要么不被支持 // 这种极端情况可以返回true,或者根据需求调整 return Intl.Collator.supportedLocalesOf(locale).length > 0; } // 测试示例 console.log(supportsLocaleForCaseConversion('tr')); // true(i转İ,和默认的I不同) console.log(supportsLocaleForCaseConversion('de')); // true(ß转ss,和默认的ß不同) console.log(supportsLocaleForCaseConversion('fake-locale-123')); // false
这个方法的准确性更高,即使遇到那种“规则和默认完全一致的locale”,最后也会 fallback 到Collator的检测结果,进一步降低误判概率。
总结一下:虽然没有官方的等效方法,但上面的两个方案完全可以满足日常开发中检测locale是否被大小写转换方法支持的需求,不需要提前了解目标locale的任何特殊规则。
内容来源于stack exchange

