如何将数字格式化为货币字符串
技术背景
在前端开发中,常常需要将数字格式化为货币字符串,以满足不同地区和业务的需求。JavaScript 提供了多种方法来实现这一功能,下面将详细介绍这些方法。
实现步骤
Intl.NumberFormat
是 JavaScript 国际化 API 的一部分,可用于格式化数字为货币字符串。
1 2 3 4 5 6 7 8 9 10 11 12 13
| const formatter = new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD', trailingZeroDisplay: 'stripIfInteger' });
let input = document.getElementById('amount'); input.addEventListener('keyup', e => { document.getElementById('result').innerText = formatter.format(e.target.value); }); input.dispatchEvent(new Event('keyup'));
|
2. 使用 Number.prototype.toLocaleString
1 2 3 4
| console.log((2500).toLocaleString('en-US', { style: 'currency', currency: 'USD', }));
|
3. 使用 Number.prototype.toFixed
1 2 3 4
| const profits = 2489.8237; console.log(profits.toFixed(3)); console.log(profits.toFixed(2)); console.log(profits.toFixed(7));
|
4. 自定义函数
1 2 3 4 5 6 7 8 9 10 11 12 13
| function formatMoney(number, decPlaces, decSep, thouSep) { decPlaces = isNaN(decPlaces = Math.abs(decPlaces)) ? 2 : decPlaces; decSep = typeof decSep === "undefined" ? "." : decSep; thouSep = typeof thouSep === "undefined" ? "," : thouSep; var sign = number < 0 ? "-" : ""; var i = String(parseInt(number = Math.abs(Number(number) || 0).toFixed(decPlaces))); var j = (j = i.length) > 3 ? j % 3 : 0;
return sign + (j ? i.substr(0, j) + thouSep : "") + i.substr(j).replace(/(\d{3})(?=\d)/g, "$1" + thouSep) + (decPlaces ? decSep + Math.abs(number - i).toFixed(decPlaces).slice(2) : ""); }
|
5. 自定义函数(ES6)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| function formatMoney(amount, decimalCount = 2, decimal = ".", thousands = ",") { try { decimalCount = Math.abs(decimalCount); decimalCount = isNaN(decimalCount) ? 2 : decimalCount;
const negativeSign = amount < 0 ? "-" : "";
let i = parseInt(amount = Math.abs(Number(amount) || 0).toFixed(decimalCount)).toString(); let j = (i.length > 3) ? i.length % 3 : 0;
return negativeSign + (j ? i.substr(0, j) + thousands : '') + i.substr(j).replace(/(\d{3})(?=\d)/g, "$1" + thousands) + (decimalCount ? decimal + Math.abs(amount - i).toFixed(decimalCount).slice(2) : ""); } catch (e) { console.log(e) } };
|
6. 短而快的解决方案
1
| (12345.67).toFixed(2).replace(/\d(?=(\d{3})+\.)/g, '$&,');
|
7. 扩展的短解决方案
1 2 3 4
| Number.prototype.format = function(n, x) { var re = '\\d(?=(\\d{' + (x || 3) + '})+' + (n > 0 ? '\\.' : '$') + ')'; return this.toFixed(Math.max(0, ~~n)).replace(new RegExp(re, 'g'), '$&,'); };
|
8. 超级扩展的短解决方案
1 2 3 4 5 6
| Number.prototype.format = function(n, x, s, c) { var re = '\\d(?=(\\d{' + (x || 3) + '})+' + (n > 0 ? '\\D' : '$') + ')', num = this.toFixed(Math.max(0, ~~n)); return (c ? num.replace('.', c) : num).replace(new RegExp(re, 'g'), '$&' + (s || ',')); };
|
核心代码
以下是使用 Intl.NumberFormat
格式化货币的核心代码:
1 2 3 4 5 6 7 8
| const formatter = new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD', trailingZeroDisplay: 'stripIfInteger' }); const amount = 2500; const formattedAmount = formatter.format(amount); console.log(formattedAmount);
|
最佳实践
- 性能优化:如果需要格式化多个数字,建议使用
Intl.NumberFormat
并在页面加载时只实例化一次,以提高性能。 - 兼容性处理:对于旧浏览器,可以使用 shim 来支持
Intl.NumberFormat
。 - 国际化支持:根据用户的地区设置,选择合适的语言代码和货币代码,以提供更好的用户体验。
常见问题
1. toLocaleString
在旧浏览器中不支持地区设置
在旧浏览器中,toLocaleString
可能不支持地区设置,建议检查 Intl
对象是否存在,或者使用 shim。
2. Node.js 不支持所有地区
Node.js 在 v13 之前只支持 en-US
,可以安装 full-icu 来解决。
3. 自定义函数中的边界情况
在使用自定义函数时,需要考虑边界情况,如负数、小数位数等,确保函数的健壮性。