JS 数字金额化的4种方法

四种方法


/**
 * 数字金额化:
 * @param {*} num 
 * 入参: 数字,例如:459087578
 * 出参:字符串并逗号分割,例如:89,459,087,578
 */

/**
 * 方法一
 */
function num2amount1(num){
  num += '';
  let ans = '';
  const len = num.length;
  for(let i = 0; i < len; i++) {
    i % 3 === 1 ? ans = num[len-i-1] + ',' + ans : ans = num[len-i-1] + ans;
  }
  return ans;
}
/**
 * 方法二
 * @param {*} num 
 */
function num2amount2(num){
  return (num).toLocaleString('en-US');
}

/**
 * 方法三
 * @param {*} num 
 */
function num2amount3(num){
  return (num+'').replace(/\B(?=(\d{3})+(?!\d))/g, ',');
}
/**
 * 方法四
 * @param {*} num 
 */
function num2amount4(num){
  return (num+'').split('').reduceRight((pre, curr, index) => index % 3 === 1 ? curr + ',' + pre : curr + pre);
}

// 测试
let num = 89787667766876;

let ans1 = num2amount1(num);
let ans2 = num2amount2(num);
let ans3 = num2amount3(num);
let ans4 = num2amount4(num);
console.log(ans1);// 89,787,667,766,876
console.log(ans2);// 89,787,667,766,876
console.log(ans3);// 89,787,667,766,876
console.log(ans4);// 89,787,667,766,876

现在看起来基本没毛病,可是能实现是一回事,能不能来出来溜溜,提供给其他人使用又是另外一回事。真实的情况很复杂多变,很多情况都需要考虑到。下面列出几个测试情况,开发也要学会弄测试用例,用测试的思维做开发,用产品的思维做开发。如果我们对num2amount函数的入参弄些不规则的值,例如如下情况。

  • 情况一:正常情况,正整数,如8887677677566
  • 情况二:非数值类型,如布尔值(true),字符串('1233456333'),对象({name:123})等
  • 情况三:负数,如-22221
  • 情况四:小数,如89877768866.098
  • 情况五:大数,如1000000000000000000000000000000
  • 情况六:边界情况,如undefine, null

我们针对以上情况对工具函数进行改造,给出的解决方案,以正则为例写出如下代码

function num2amount(num){
  let suffix='';
  let numStr='';
  if (isNumber(num) || isNumberString(num) || isBigInt(num)) {
    // 判断是否为负数,大数超过MAX_SAFE_INTEGER,
    if(Number(num) < 0) return 0;
    if(isBigInt(num)) return String(num).replace(/\B(?=(\d{3})+(?!\d))/g, ',');
    numStr=String(num);
    // 判断小数
    if(String(num).indexOf('.')>0) {
      numStr=Number(num).toFixed(2);
      splitStr=numStr.split('.');
      numStr=splitStr[0];
      suffix=`.${splitStr[1]}`;
    }
    return numStr.replace(/\B(?=(\d{3})+(?!\d))/g, ',')+suffix;
  }
  return '-';
}
//是否是有效的数字类型
function isNumber(num){
  return typeof num == 'number' && !isNaN(num);
}
// 判断是否是任意大的整数
function isBigInt(num){
  return typeof num == 'bigint';
}
// 判断是否为有效的数字字符串
function isNumberString(str){
  return typeof str == 'string' && !isNaN(Number(str));
}


// 测试结果
let ans1 = num2amount('1233456333');//1,233,456
let ans2 = num2amount(true);// -
let ans3 = num2amount(-2); // 0
let ans4 = num2amount(89877768866.098); // 877,768,866.10
let ans5 = num2amount(1000000000000000000000000000000n);//1,000,000,000,000,000,000,000,000,000,000
let ans6 = num2amount(null); // -
let ans7 = num2amount(); // -

总结一下,看起来写一个工具函数没什么难度,其实就连简单的功能也不是那么容易的。都要考虑到方方面面,容错处理尤其重要。以上代码依旧不够简洁,以后发现有更好的实现方式再回来修改。

posted @ 2020-11-05 16:04  mingL  阅读(1062)  评论(0编辑  收藏  举报