JavaScript实现数字千分位格式化的6种方案与性能对比

作者:极速慢跑时间:2026-10-28 23:32:30浏览:291

本文深入解析JavaScript中实现数字千分位格式化的六种常见方法,涵盖数组操作、字符串拼接、正则匹配及截取等技巧。通过对比不同数值下的执行耗时,分析各方案在循环次数、正则消耗及内存使用上的差异,最终推荐综合性能最优的slice截取方案,帮助开发者在代码简洁性与运行效率间做出最佳选择。

JavaScript实现数字千分位格式化的6种方案与性能对比

数字千分位格式是指从个位数开始,每三位数字之间插入一个逗号,例如“10,000”。针对这一需求,最初编写的函数实现如下:

方法一:数组操作法

代码如下:

// 方法一
function toThousands(num) {
var result = [ ], counter = 0;
num = (num || 0).toString().split('');
for (var i = num.length - 1; i >= 0; i--) {
counter++;
result.unshift(num[i]);
if (!(counter % 3) && i != 0) { result.unshift(','); }
    }
return result.join('');
}

方法一的执行逻辑是将数字转换为字符串后拆分为数组,随后从末尾开始逐个将元素插入到新数组(result)的头部。每插入一个元素,计数器counter加1,当counter为3的倍数且非首位(i不为0)时插入逗号。最后通过join方法合并数组得到结果。

该方法逻辑清晰,曾在项目中应用一段时间。但直觉表明其性能表现不佳。

方法二:字符串拼接法

方法二——方法一的字符串版

代码如下:

// 方法二
function toThousands(num) {
var result = '', counter = 0;
num = (num || 0).toString();
for (var i = num.length - 1; i >= 0; i--) {
counter++;
result = num.charAt(i) + result;
if (!(counter % 3) && i != 0) { result = ',' + result; }
    }
return result;
}

方法二是对方法一的优化,不再将字符串拆分为数组,而是全程对字符串进行操作。

方法三:正则匹配法

方法三——循环匹配末尾的三个数字

代码如下:

// 方法三
function toThousands(num) {
var num = (num || 0).toString(), re = /\d{3}$/, result = '';
while ( re.test(num) ) {
result = RegExp.lastMatch + result;
if (num !== RegExp.lastMatch) {
result = ',' + result;
num = RegExp.leftContext;
} else {
num = '';
break;
        }
    }
if (num) { result = num + result; }
return result;
}

方法三采用完全不同的算法,通过正则表达式循环匹配末尾的三个数字。每次匹配成功后,将匹配内容和逗号插入结果字符串头部,并将num更新为剩余未匹配部分(RegExp.leftContext)。需注意以下两点:

1. 若数字位数为3的倍数,最后一次匹配的是三个数字,但最前面的三个数字前无需加逗号; 2. 若数字位数不是3的倍数,循环结束后num变量会剩余1到2个数字,需将剩余数字插入结果字符串头部。

虽然方法三减少了循环次数(每次处理三个字符),但由于使用了正则表达式,一定程度上增加了额外消耗。

方法四:字符串截取法

方法四——方法三的字符串版

代码如下:

// 方法四
function toThousands(num) {
var num = (num || 0).toString(), result = '';
while (num.length > 3) {
result = ',' + num.slice(-3) + result;
num = num.slice(0, num.length - 3);
    }
if (num) { result = num + result; }
return result;
}

事实上,截取末尾三个字符的功能可以通过字符串类型的slice、substr或substring方法实现,从而避免使用正则表达式。

方法五:分组合并法

方法五——分组合并法

代码如下:

// 方法五
function toThousands(num) {
var num = (num || 0).toString(), temp = num.length % 3;
switch (temp) {
case 1:
num = '00' + num;
break;
case 2:
num = '0' + num;
break;
    }
return num.match(/\d{3}/g).join(',').replace(/^0+/, '');
}

该方法先将数字位数补足为3的倍数,利用正则表达式将其切割为每三个数字一组,再通过join方法添加逗号,最后移除补位的0。

方法六:正则替换法

方法六——懒人法

代码如下:

// 方法六
function toThousands(num) {
return (num || 0).toString().replace(/(\d)(?=(?:\d{3})+$)/g, '$1,');
}

一直认为格式化可以通过一条正则表达式替换完成,这需要用到断言等写法。经Google搜索,确实找到这条正则表达式,这可能是代码最短的实现方式。

性能测试结果与分析

测试结果

数字 执行5000次消耗的时间(ms)
方法一 方法二 方法三 方法四 方法五 方法六
1 4 1 3 1 14 2
10 14 1 3 0 7 2
100 12 1 2 4 5 3
1000 13 2 3 2 9 5
10000 21 4 3 1 6 3
100000 21 3 2 1 5 6

方法一和方法二的强烈对比表明,字符串操作的效率远高于数组操作;方法六的测试结果说明代码长短与性能高低无直接关系。方法四的综合性能最佳(尽管num为100时性能略有下降,原因尚不明确),主要原因在于:

1. 对比方法一、二,每次操作3个字符而非1个,减少了循环次数; 2. 对比方法三、五、六,未使用正则表达式,减少了额外消耗。

最终选择方法四作为优化方案。如有更好的实现方法或建议,欢迎评论交流。

作者最新文章