为什么toLocaleString生成的货币字符串与静态字符串对比不相等?
问题根因
两个字符串视觉上完全一致但比对失败,和欧元符号本身无关,核心差异是金额与欧元符号之间的空格类型:
toLocaleString('de', {currency: 'EUR'})生成的字符串中,金额和欧元符号间的是不间断空格(Unicode编码为\u00A0),这是德语区货币格式的官方规范,避免金额和货币符号被换行拆分- 手动声明的静态字符串
'2,00 €'中,中间的是普通半角空格(Unicode编码为\u0020)
你可以用以下代码验证字符编码差异:
// 逐字符打印Unicode编码 console.log([...localStringValue].map(char => `${char}: 0x${char.charCodeAt(0).toString(16)}`)); console.log([...stringValue].map(char => `${char}: 0x${char.charCodeAt(0).toString(16)}`));
运行后可以看到:localStringValue对应空格位置的编码为0xa0,stringValue对应空格位置编码为0x20,这就是所有比对逻辑返回不相等的原因。
解决方案
根据使用场景可以选择以下任意一种处理方式:
- 方案1:将动态生成的字符串中的不间断空格统一替换为普通空格后比对
const normalizedLocalValue = localStringValue.replace(/\u00A0/g, ' '); console.log(normalizedLocalValue === stringValue); // 输出 true
- 方案2:手动声明静态字符串时直接使用不间断空格
const stringValue = '2,00\u00A0€'; console.log(localStringValue === stringValue); // 输出 true
- 方案3:通用货币字符串规范化方法,适配多地区货币比对场景
function normalizeCurrencyStr(str) { // 统一所有空格类型为普通空格,可根据需求补充统一小数点、千分位的逻辑 return str.replace(/\s/g, ' ').trim(); } console.log(normalizeCurrencyStr(localStringValue) === normalizeCurrencyStr(stringValue)); // 输出 true
内容的提问来源于stack exchange,提问作者Franki1986
相关产品推荐
相关产品推荐

