我想用JavaScript格式化价格。我想要一个函数,它将浮点作为参数,并返回如下格式的字符串:
"$ 2,500.00"
我该怎么做?
我想用JavaScript格式化价格。我想要一个函数,它将浮点作为参数,并返回如下格式的字符串:
"$ 2,500.00"
我该怎么做?
当前回答
通常,有多种方法可以执行相同的操作,但我会避免使用Number.prototype.toLocaleString,因为它可以根据用户设置返回不同的值。
我也不建议扩展Number.prototype-扩展原生对象原型是一种糟糕的做法,因为它可能会与其他人的代码(例如库/框架/插件)发生冲突,并且可能与未来的JavaScript实现/版本不兼容。
我认为正则表达式是解决这个问题的最佳方法,下面是我的实现:
/**
* Converts number into currency format
* @param {number} number Number that should be converted.
* @param {string} [decimalSeparator] Decimal separator, defaults to '.'.
* @param {string} [thousandsSeparator] Thousands separator, defaults to ','.
* @param {int} [nDecimalDigits] Number of decimal digits, defaults to `2`.
* @return {string} Formatted string (e.g. numberToCurrency(12345.67) returns '12,345.67')
*/
function numberToCurrency(number, decimalSeparator, thousandsSeparator, nDecimalDigits){
//default values
decimalSeparator = decimalSeparator || '.';
thousandsSeparator = thousandsSeparator || ',';
nDecimalDigits = nDecimalDigits == null? 2 : nDecimalDigits;
var fixed = number.toFixed(nDecimalDigits), //limit/add decimal digits
parts = new RegExp('^(-?\\d{1,3})((?:\\d{3})+)(\\.(\\d{'+ nDecimalDigits +'}))?$').exec( fixed ); //separate begin [$1], middle [$2] and decimal digits [$4]
if(parts){ //number >= 1000 || number <= -1000
return parts[1] + parts[2].replace(/\d{3}/g, thousandsSeparator + '$&') + (parts[4] ? decimalSeparator + parts[4] : '');
}else{
return fixed.replace('.', decimalSeparator);
}
}
其他回答
一个简单的选项,通过先反转字符串和基本正则表达式来正确放置逗号。
String.prototype.reverse = function() {
return this.split('').reverse().join('');
};
Number.prototype.toCurrency = function( round_decimal /*boolean*/ ) {
// format decimal or round to nearest integer
var n = this.toFixed( round_decimal ? 0 : 2 );
// convert to a string, add commas every 3 digits from left to right
// by reversing string
return (n + '').reverse().replace( /(\d{3})(?=\d)/g, '$1,' ).reverse();
};
一种仅满足原始要求的极简方法:
function formatMoney(n) {
return "$ " + (Math.round(n * 100) / 100).toLocaleString();
}
@丹尼尔·马格廖拉:你说得对。以上是一个仓促而不完整的实施。以下是正确的实施方式:
function formatMoney(n) {
return "$ " + n.toLocaleString().split(".")[0] + "."
+ n.toFixed(2).split(".")[1];
}
http://code.google.com/p/javascript-number-formatter/:
短、快、灵活但独立。只有75行,包括MIT许可证信息、空白行和注释。接受标准数字格式,如#、##0.00或带否定的-000.####。接受任何国家/地区格式,如###0,00,#,###.##,#‘###.##或任何类型的非编号符号。接受任意数字分组。#、##、#0.000或#、####0.##均有效。接受任何冗余/防傻瓜格式。##、###、##。#或0#、#00####0#都正常。自动数字舍入。简单的界面,只需提供如下掩码和值:格式(“0.0000”,3.141592)
UPDATE这是我自己开发的应用程序,用于最常见的任务:
var NumUtil = {};
/**
Petty print 'num' wth exactly 'signif' digits.
pp(123.45, 2) == "120"
pp(0.012343, 3) == "0.0123"
pp(1.2, 3) == "1.20"
*/
NumUtil.pp = function(num, signif) {
if (typeof(num) !== "number")
throw 'NumUtil.pp: num is not a number!';
if (isNaN(num))
throw 'NumUtil.pp: num is NaN!';
if (num < 1e-15 || num > 1e15)
return num;
var r = Math.log(num)/Math.LN10;
var dot = Math.floor(r) - (signif-1);
r = r - Math.floor(r) + (signif-1);
r = Math.round(Math.exp(r * Math.LN10)).toString();
if (dot >= 0) {
for (; dot > 0; dot -= 1)
r += "0";
return r;
} else if (-dot >= r.length) {
var p = "0.";
for (; -dot > r.length; dot += 1) {
p += "0";
}
return p+r;
} else {
return r.substring(0, r.length + dot) + "." + r.substring(r.length + dot);
}
}
/** Append leading zeros up to 2 digits. */
NumUtil.align2 = function(v) {
if (v < 10)
return "0"+v;
return ""+v;
}
/** Append leading zeros up to 3 digits. */
NumUtil.align3 = function(v) {
if (v < 10)
return "00"+v;
else if (v < 100)
return "0"+v;
return ""+v;
}
NumUtil.integer = {};
/** Round to integer and group by 3 digits. */
NumUtil.integer.pp = function(num) {
if (typeof(num) !== "number") {
console.log("%s", new Error().stack);
throw 'NumUtil.integer.pp: num is not a number!';
}
if (isNaN(num))
throw 'NumUtil.integer.pp: num is NaN!';
if (num > 1e15)
return num;
if (num < 0)
throw 'Negative num!';
num = Math.round(num);
var group = num % 1000;
var integ = Math.floor(num / 1000);
if (integ === 0) {
return group;
}
num = NumUtil.align3(group);
while (true) {
group = integ % 1000;
integ = Math.floor(integ / 1000);
if (integ === 0)
return group + " " + num;
num = NumUtil.align3(group) + " " + num;
}
return num;
}
NumUtil.currency = {};
/** Round to coins and group by 3 digits. */
NumUtil.currency.pp = function(amount) {
if (typeof(amount) !== "number")
throw 'NumUtil.currency.pp: amount is not a number!';
if (isNaN(amount))
throw 'NumUtil.currency.pp: amount is NaN!';
if (amount > 1e15)
return amount;
if (amount < 0)
throw 'Negative amount!';
if (amount < 1e-2)
return 0;
var v = Math.round(amount*100);
var integ = Math.floor(v / 100);
var frac = NumUtil.align2(v % 100);
var group = integ % 1000;
integ = Math.floor(integ / 1000);
if (integ === 0) {
return group + "." + frac;
}
amount = NumUtil.align3(group);
while (true) {
group = integ % 1000;
integ = Math.floor(integ / 1000);
if (integ === 0)
return group + " " + amount + "." + frac;
amount = NumUtil.align3(group) + " " + amount;
}
return amount;
}
function CurrencyFormatted(amount)
{
var i = parseFloat(amount);
if(isNaN(i)) { i = 0.00; }
var minus = '';
if(i < 0) { minus = '-'; }
i = Math.abs(i);
i = parseInt((i + .005) * 100);
i = i / 100;
s = new String(i);
if(s.indexOf('.') < 0) { s += '.00'; }
if(s.indexOf('.') == (s.length - 2)) { s += '0'; }
s = minus + s;
return s;
}
来自WillMaster。
看看JavaScriptNumber对象,看看它是否可以帮助您。
toLocaleString()将使用位置特定的千位分隔符格式化数字。toFixed()将数字舍入到特定的小数位数。
要同时使用这些值,必须将其类型改回数字,因为它们都输出字符串。
例子:
Number((someNumber).toFixed(1)).toLocaleString()
EDIT
您可以直接使用toLocaleString,而不必重新转换为数字:
someNumber.toLocaleString(undefined, {minimumFractionDigits: 2, maximumFractionDigits: 2});
多个数字
如果需要经常以类似的方式格式化数字,可以创建一个特定的对象以供重用。德语(瑞士):
const money = new Intl.NumberFormat('de-CH',
{ style:'currency', currency: 'CHF' });
const percent = new Intl.NumberFormat('de-CH',
{ style:'percent', maximumFractionDigits: 1, signDisplay: "always"});
其可以用作:
money.format(1234.50); // output CHF 1'234.50
percent.format(0.083); // output +8.3%
非常漂亮。