我想用JavaScript格式化价格。我想要一个函数,它将浮点作为参数,并返回如下格式的字符串:

"$ 2,500.00"

我该怎么做?


当前回答

一种仅满足原始要求的极简方法:

function formatMoney(n) {
    return "$ " + (Math.round(n * 100) / 100).toLocaleString();
}

@丹尼尔·马格廖拉:你说得对。以上是一个仓促而不完整的实施。以下是正确的实施方式:

function formatMoney(n) {
    return "$ " + n.toLocaleString().split(".")[0] + "."
        + n.toFixed(2).split(".")[1];
}

其他回答

function getMoney(A){
    var a = new Number(A);
    var b = a.toFixed(2); // Get 12345678.90
    a = parseInt(a); // Get 12345678
    b = (b-a).toPrecision(2); // Get 0.90
    b = parseFloat(b).toFixed(2); // In case we get 0.0, we pad it out to 0.00
    a = a.toLocaleString(); // Put in commas - Internet Explorer also puts in .00, so we'll get 12,345,678.00
    // If Internet Explorer (our number ends in .00)
    if(a < 1 && a.lastIndexOf('.00') == (a.length - 3))
    {
        a = a.substr(0, a.length-3); // Delete the .00
    }
    return a + b.substr(1); // Remove the 0 from b, then return a + b = 12,345,678.90
}
alert(getMoney(12345678.9));

这适用于Firefox和Internet Explorer。

YUI代码库使用以下格式:

format: function(nData, oConfig) {
    oConfig = oConfig || {};

    if(!YAHOO.lang.isNumber(nData)) {
        nData *= 1;
    }

    if(YAHOO.lang.isNumber(nData)) {
        var sOutput = nData + "";
        var sDecimalSeparator = (oConfig.decimalSeparator) ? oConfig.decimalSeparator : ".";
        var nDotIndex;

        // Manage decimals
        if(YAHOO.lang.isNumber(oConfig.decimalPlaces)) {
            // Round to the correct decimal place
            var nDecimalPlaces = oConfig.decimalPlaces;
            var nDecimal = Math.pow(10, nDecimalPlaces);
            sOutput = Math.round(nData*nDecimal)/nDecimal + "";
            nDotIndex = sOutput.lastIndexOf(".");

            if(nDecimalPlaces > 0) {
                // Add the decimal separator
                if(nDotIndex < 0) {
                    sOutput += sDecimalSeparator;
                    nDotIndex = sOutput.length-1;
                }
                // Replace the "."
                else if(sDecimalSeparator !== "."){
                    sOutput = sOutput.replace(".",sDecimalSeparator);
                }
                // Add missing zeros
                while((sOutput.length - 1 - nDotIndex) < nDecimalPlaces) {
                    sOutput += "0";
                }
            }
        }

        // Add the thousands separator
        if(oConfig.thousandsSeparator) {
            var sThousandsSeparator = oConfig.thousandsSeparator;
            nDotIndex = sOutput.lastIndexOf(sDecimalSeparator);
            nDotIndex = (nDotIndex > -1) ? nDotIndex : sOutput.length;
            var sNewOutput = sOutput.substring(nDotIndex);
            var nCount = -1;
            for (var i=nDotIndex; i>0; i--) {
                nCount++;
                if ((nCount%3 === 0) && (i !== nDotIndex)) {
                    sNewOutput = sThousandsSeparator + sNewOutput;
                }
                sNewOutput = sOutput.charAt(i-1) + sNewOutput;
            }
            sOutput = sNewOutput;
        }

        // Prepend prefix
        sOutput = (oConfig.prefix) ? oConfig.prefix + sOutput : sOutput;

        // Append suffix
        sOutput = (oConfig.suffix) ? sOutput + oConfig.suffix : sOutput;

        return sOutput;
    }
    // Still not a number. Just return it unaltered
    else {
        return nData;
    }
}

它需要编辑,因为YUI库是可配置的,比如用“.”替换oConfig.decimalSeparator。

快速快捷的解决方案(适用于任何地方!)

(12345.67).toFixed(2).replace(/\d(?=(\d{3})+\.)/g, '$&,');  // 12,345.67

此解决方案背后的思想是用第一个匹配和逗号替换匹配的部分,即“$&,”。匹配是使用前瞻方法完成的。您可以将表达式读为“匹配一个数字,如果它后面跟着三个数字集(一个或多个)和一个点的序列”。

测验:

1        --> "1.00"
12       --> "12.00"
123      --> "123.00"
1234     --> "1,234.00"
12345    --> "12,345.00"
123456   --> "123,456.00"
1234567  --> "1,234,567.00"
12345.67 --> "12,345.67"

演示:http://jsfiddle.net/hAfMM/9571/


扩展短解决方案

您还可以扩展Number对象的原型,以添加对任意数量的小数[0..n]和数字组大小[0..x]的额外支持:

/**
 * Number.prototype.format(n, x)
 * 
 * @param integer n: length of decimal
 * @param integer x: length of sections
 */
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'), '$&,');
};

1234..format();           // "1,234"
12345..format(2);         // "12,345.00"
123456.7.format(3, 2);    // "12,34,56.700"
123456.789.format(2, 4);  // "12,3456.79"

演示/测试:http://jsfiddle.net/hAfMM/435/


超扩展短解决方案

在此超级扩展版本中,您可以设置不同的分隔符类型:

/**
 * Number.prototype.format(n, x, s, c)
 * 
 * @param integer n: length of decimal
 * @param integer x: length of whole part
 * @param mixed   s: sections delimiter
 * @param mixed   c: decimal delimiter
 */
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 || ','));
};

12345678.9.format(2, 3, '.', ',');  // "12.345.678,90"
123456.789.format(4, 4, ' ', ':');  // "12 3456:7890"
12345678.9.format(0, 3, '-');       // "12-345-679"

演示/测试:http://jsfiddle.net/hAfMM/612/

处理货币输出(包括负数)的函数。样本输出:$5.23-$5.23

function formatCurrency(total) {
    var neg = false;
    if(total < 0) {
        neg = true;
        total = Math.abs(total);
    }
    return (neg ? "-$" : '$') + parseFloat(total, 10).toFixed(2).replace(/(\d)(?=(\d{3})+\.)/g, "$1,").toString();
}

JavaScript中没有“formatNumber”的等价物。你可以自己写,也可以找一个已经这样做的库。