先看一些实际的例子:
var oFormat = NumberFormat.getCurrencyInstance({ "currencyCode": false, "customCurrencies": { "BTC": { "symbol": "\u0243", "decimals": 3 } } }); oFormat.format(123.4567, "BTC"); // "Ƀ 123.457"
上面的例子,定义了一个名为 BTC 的自定义货币符号,同时用 decimals 指定小数点后的数位,以及货币符号的 unicode 编码值。
运行结果如下:
另一个例子:
var oFormat = NumberFormat.getCurrencyInstance({ "currencyCode": false, "customCurrencies": { "MyDollar": { "isoCode": "USD", "decimals": 3 }, "Bitcoin": { "decimals": 2 } } }); // symbol looked up from global configuration oFormat.format(123.4567, "MyDollar"); // "$123.457" // no symbol available, custom currency key is rendered oFormat.format(777.888, "Bitcoin"); // "Bitcoin 777.89"
我们来单步调试查看 format 函数的执行原理。
进入 Currency.js 的 formatValue 方法。输入参数为 87.2 和 EUR:
目标类型为 string 字符串,所以进入 case string 的分支:
*/ Currency.prototype.formatValue = function(vValue, sTargetType) { var aValues = vValue; if (vValue == undefined || vValue == null) { return null; } if (this.oInputFormat) { aValues = this.oInputFormat.parse(vValue); } if (!Array.isArray(aValues)) { throw new FormatException("Cannot format currency: " + vValue + " has the wrong format"); } if ((aValues[0] == undefined || aValues[0] == null) && this.bShowNumber) { return null; } switch (this.getPrimitiveType(sTargetType)) { case "string": return this.oOutputFormat.format(aValues); default: throw new FormatException("Don't know how to format currency to " + sTargetType); } };
读取 EUR 对应的 digit 数位:
所有的格式都存储在 LocaleData 里:
找不到 EUR 对应的 digit 值:
于是读取 default 配置。如果 default 配置也为空,就返回默认的 2.
default 值维护在此处:2
此处把 87 和 2 使用小数点分隔开,放到不同的变量里分别存储:
iDotPos = sNumber.indexOf("."); if (iDotPos > -1) { sIntegerPart = sNumber.substr(0, iDotPos); sFractionPart = sNumber.substr(iDotPos + 1); } else { sIntegerPart = sNumber; }
最终的格式化结果:87.20
看另一个例子:9.99999 EUR
这里 preserveDecimals 的值为 true,因此 9.99999 小数点后的五个 9,会被保留下来。
如果我们把 preserveDecimals 的值改为 false,
最后显示的值就四舍五入变成了 10.00: