Фронтальное форматирование суммы

внешний интерфейс JavaScript

«Это третий день моего участия в ноябрьском испытании обновлений. Подробную информацию об этом событии см.:Вызов последнего обновления 2021 г."

Во фронтенд-проектах отображение в формате количества является очень распространенным требованием, здесь разбираются некоторые распространенные методы обработки, такие как toLocaleString(), регулярное сопоставление, перехват цикла slice() и т. д., а также решается проблема точности десятичной точки.

в качестве примера:12341234.246 => ¥ 12,341,234.25

Способ 1: Используйте встроенный браузерNumber.prototype.toLocaleString()Обработка целой части и непосредственное использование десятичной частиNumber.prototype.toFixed()Округления

// v1.0
const formatMoney = (money, symbol = "", decimals = 2) => {
  if (!(money && money > 0)) {
    return 0.0;
  }

  let arr = money.toFixed(decimals).toString().split(".");
  let first = parseInt(arr[0]).toLocaleString();
  let result = [first, arr[1]].join(".");
  return `${symbol} ${money.toFixed(decimals)}`;
};

formatMoney(12341234.246); // 12,341,234.25
formatMoney(12341234.246, "¥", 1); // ¥ 12,341,234.2

2021.11.9 Изменить запись Раньше я писал сложные вещи.После указаний [Хуан Цзиншэн] в области комментариев оптимизация выглядит следующим образом:

// v2.0 简化函数
const formatMoney = (money, symbol = "", decimals = 2) =>
      `${symbol} ${parseFloat(money.toFixed(decimals)).toLocaleString()}`;
      
formatMoney(12341234.246, "¥", 2) // ¥ 12,341,234.25

// 或者只用toLocaleString()处理
const format = (money, decimals = 2) =>
  money.toLocaleString("zh", {
    style: "currency",
    currency: "CNY",
    maximumFractionDigits: decimals,
    useGrouping: true, // false-没有千位分隔符;true-有千位分隔符
  });
format(12341234.246); // ¥12,341,234.25

2021.11.10 Изменить запись После подсказки в области комментариев [Вы касаетесь моего материала] проблема с ошибкой точности toFixed() была решена.Подробности см.Прецизионная обработка десятичного отображения во внешнем интерфейсе

// 测试数据如下:
formatMoney(12.035); // 12.04 正常四舍五入
formatMoney(12.045); // 12.04 异常,应该为12.05,没有四舍五入

// v3.0 解决toFixed()问题
const formatToFixed = (money, decimals = 2) => {
  return (
    Math.round((parseFloat(money) + Number.EPSILON) * Math.pow(10, decimals)) /
    Math.pow(10, decimals)
  ).toFixed(decimals);
};
const formatMoney = (money, symbol = "", decimals = 2) =>
  `${symbol}${parseFloat(formatToFixed(money, decimals)).toLocaleString()}`;

formatMoney(12341234.035, '¥'); // ¥12,341,234.04
formatMoney(12341234.045, '¥'); // ¥12,341,234.05

17.11.2021 Изменить запись Решена проблема с сохранением четырех знаков после запятой через напоминание в области комментариев [Ryan_zhang]

// v4.0 只更改了formatMoney函数,其他的不变
const formatMoney = (money, symbol = "", decimals = 2) =>
  `${symbol}${parseFloat(formatToFixed(money, decimals)).toLocaleString(
    "zh",
    {
      maximumFractionDigits: decimals,
      useGrouping: true,
    }
  )}`;
formatMoney(12341234.12335, "¥", 4); // ¥12,341,234.1234
formatMoney(12341234.12345, "¥", 4); // ¥12,341,234.1235

Способ 2: используйте регулярные выражения для обработки целой части, а десятичная часть такая же, как указано выше. имеет"Обычная мини-книга JS"Хорошо вводить регулярные выражения.В главе 2.4.2 я говорил о «представлении чисел с разделителем тысяч».Введение очень подробное, и рекомендуется взглянуть.

  • \b: граница слова, в частности, позиция между \w и \W, а также позиция между \w и ^ и позиция между \w и $
  • \B: противоположность \b, а не граница слова
  • (?=p): где p — подшаблон, то есть позиция перед p или символ после позиции должны совпадать с p
/**
 * @params {Number} money 金额
 * @params {Number} decimals 保留小数点后位数
 * @params {String} symbol 前置符号
 */
const formatMoney = (money, symbol = "", decimals = 2) => {
  let result = money
    .toFixed(decimals)
    .replace(/\B(?=(\d{3})+\b)/g, ",")
    .replace(/^/, `${symbol}`);
  return result;
};

formatMoney(12341234.246, "$", 2); // $12,341,234.25

// v2.0 解决toFixed()问题
const formatMoneyNew = (money, symbol = "", decimals = 2) =>
  formatToFixed(money, decimals)
    .replace(/\B(?=(\d{3})+\b)/g, ",")
    .replace(/^/, `${symbol}`);

formatMoneyNew(12341234.035, "¥", 2); // ¥12,341,234.04
formatMoneyNew(12341234.045, "¥", 2); // ¥12,341,234.05

Способ 3: зацикливание строк, реализованное путем перехвата фрагмента

  • подстрока (начало, конец): содержит начало, а не конец
  • substr(start, length): содержит начало, длина равна длине
  • slice(start, end): работает с массивами и строками; включает начало, а не конец
  • splice(start, length, items): только для массивов, возможны добавления, удаления и изменения
const formatMoney = (money, symbol = "", decimals = 2) => {
  // 改造前
  // let arr = money.toFixed(decimals).toString().split(".");
  // 改造后
  let arr = formatToFixed(money, decimals).toString().split(".");
  let num = arr[0];
  let first = "";
  su;
  while (num.length > 3) {
    first = "," + num.slice(-3) + first;
    num = num.slice(0, num.length - 3);
  }
  if (num) {
    first = num + first;
  }
  return `${symbol} ${[first, arr[1]].join(".")}`;
};

formatMoney(12341234.246, "$", 2); // $ 12,341,234.25
formatMoney(12341234.035, "¥", 2); // ¥ 12,341,234.04
formatMoney(12341234.045, "¥", 2); // ¥ 12,341,234.05

2021.11.24 Изменить запись Через напоминания [SpriteBoy] и [maxx] в области комментариев попробуйте использовать встроенный NumberFormat Intl

Способ четвертый:Intl.NumberFormat, использование очень похоже на toLocaleString()

const formatMoney = (money, decimals = 2) => {
  return new Intl.NumberFormat("zh-CN", {
    style: "currency", // 货币形式
    currency: "CNY", // "CNY"是人民币
    currencyDisplay: "symbol", // 默认“symbol”,中文中代表“¥”符号
    // useGrouping: true, // 是否使用分组分隔符,如千位分隔符或千/万/亿分隔符,默认为true
    // minimumIntegerDigits: 1, // 使用的整数数字的最小数目.可能的值是从1到21,默认值是1
    // minimumFractionDigits: 2, // 使用的小数位数的最小数目.可能的值是从 0 到 20
    maximumFractionDigits: decimals, // 使用的小数位数的最大数目。可能的值是从 0 到 20
  }).format(money);
};

console.log(formatMoney(12341234.2, 2)); // ¥12,341,234.20
console.log(formatMoney(12341234.246, 1)); // ¥12,341,234.2
console.log(formatMoney(12341234.035, 2)); // ¥12,341,234.04
console.log(formatMoney(12341234.045, 2)); // ¥12,341,234.05
console.log(formatMoney(12341234.12335, 4)); // ¥12,341,234.1234
console.log(formatMoney(12341234.12345, 4)); // ¥12,341,234.1235