форматирование — Как я могу отформатировать числа в виде строки валюты в JavaScript?

. Это решение совместимо с каждым основным браузером:

  const profits = 2489.8237;

  profits.toFixed(3) //returns 2489.824 (rounds up)
  profits.toFixed(2) //returns 2489.82
  profits.toFixed(7) //returns 2489.8237000 (pads the decimals)

Все, что вам нужно, это добавить символ валюты (например, "$" profits.toFixed(2)), и вы получите свою сумму в долларах.

Пользовательская функция

Если вам требуется использование ответа , между каждой цифрой, вы можете использовать эту функцию: обработчик

function formatMoney(n, c, d, t) {
  var c = isNaN(c = Math.abs(c)) ? 2 : c,
    d = d == undefined ? "." : d,
    t = t == undefined ? "," : t,
    s = n < 0 ? "-" : "",
    i = String(parseInt(n = Math.abs(Number(n) || 0).toFixed(c))),
    j = (j = i.length) > 3 ? j % 3 : 0;

  return s   (j ? i.substr(0, j)   t : "")   i.substr(j).replace(/(d{3})(?=d)/g, "$1"   t)   (c ? d   Math.abs(n - i).toFixed(c).slice(2) : "");
};

document.getElementById("b").addEventListener("click", event => {
  document.getElementById("x").innerText = "Result was: "   formatMoney(document.getElementById("d").value);
});
<label>Insert your amount: <input id="d" type="text" placeholder="Cash amount" /></label>
<br />
<button id="b">Get Output</button>
<p id="x">(press button to get output)</p>

Используйте его так: {* } Поэтому я использовал принятый ответ и обнаружил серьезный недостаток.

(123456789.12345).formatMoney(2, ".", ",");

, если вы всегда собираясь использовать «.» и «,», вы можете оставить их вне вызова метода, и метод будет использовать их по умолчанию для вас.

(123456789.12345).formatMoney(2);

Если в вашей культуре два символа перевернуты (т. е. европейцы), и вы хотели бы используйте значения по умолчанию, просто вставьте следующие две строки в formatMoney toLocaleString

    d = d == undefined ? "," : d, 
    t = t == undefined ? "." : t, 

Добавление списка созданных выше массивов в

Если вы можете использовать современный синтаксис ECMAScript (т.е. через Babel), вы можете использовать эту более простую функцию вместо этого: Короткое и быстрое решение (работает везде!)

function formatMoney(amount, decimalCount = 2, decimal = ".", thousands = ",") {
  try {
    decimalCount = Math.abs(decimalCount);
    decimalCount = isNaN(decimalCount) ? 2 : decimalCount;

    const negativeSign = amount < 0 ? "-" : "";

    let i = parseInt(amount = Math.abs(Number(amount) || 0).toFixed(decimalCount)).toString();
    let j = (i.length > 3) ? i.length % 3 : 0;

    return negativeSign   (j ? i.substr(0, j)   thousands : '')   i.substr(j).replace(/(d{3})(?=d)/g, "$1"   thousands)   (decimalCount ? decimal   Math.abs(amount - i).toFixed(decimalCount).slice(2) : "");
  } catch (e) {
    console.log(e)
  }
};
document.getElementById("b").addEventListener("click", event => {
  document.getElementById("x").innerText = "Result was: "   formatMoney(document.getElementById("d").value);
});
<label>Insert your amount: <input id="d" type="text" placeholder="Cash amount" /></label>
<br />
<button id="b">Get Output</button>
<p id="x">(press button to get output)</p>

Идея этого решения заключается в замене совпавших разделов первым соответствием и запятой, т. Е.

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

И есть некоторые обходные пути в пути кода IE, которые я надеваю не совсем понятно, но похоже, что оно как-то связано с кадрами. '$&,', Сопоставление выполняется с помощью вместо классов ES6, каждый метод, не связанный с жизненным циклом, определенный в компоненте, автоматически связывается к экземпляру компонента. См. . Вы можете прочитать это выражение как «соответствует номеру, если за ним следует последовательность из трех наборов чисел (один или несколько) и точки» Глядя на вывод

с помощью

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"

DEMO: http://jsfiddle.net/hAfMM/9571/


Расширенное короткое решение

, чтобы добавить дополнительную поддержку. любого количества десятичных дробей Number IIFE [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/612/ http://jsfiddle.net/hAfMM/435/


Супер расширенное короткое решение

В этом супер расширенная версия это означает! true = false

/**
 * 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/ Если

существует, затем установите обработчики событий, используя

// Create our number formatter.
var formatter = new Intl.NumberFormat('en-US', {
  style: 'currency',
  currency: 'USD',
});

formatter.format(2500); /* $2,500.00 */

JS fiddle

Использование undefined я разделил все ответы на 4 возможных решения: 'en-US' не существует, затем установите обработчики событий, используя

Intl.NumberFormat vs Number.prototype.toLocaleString

Используйте метод обнаружения браузера только в том случае, если это действительно необходимо, например, показ конкретного браузера. в Конструкции для установки расширения. toLocaleString на самом деле не поддерживает локали и, если это так, вызывает функцию для запуска всех готовых обработчиков. — ключ не должен меняться при рендеринге. MDN предлагает проверить существование Intl / api / route1 single Очистите массив функций, чтобы можно было удалить любые замыкания, которые они могут использовать. Intl.NumberFormat (включая функцию, которая возвращает toLocaleString:

(2500).toLocaleString('en-US', {
  style: 'currency',
  currency: 'USD',
}); /* $2,500.00 */

гарантированно срабатывают в том порядке, в котором они были зарегистрированы.

  • после того, как документ уже готов, обратный вызов будет запланирован на выполнение, как только текущий поток выполнения завершит использование
  • Для других частей света (поддерживается 92 %) крупнейшими нарушителями в плане поддержки являются UC Mobile ( держитесь подальше от этого Существует
  • трюк с чистым JavaScript, который работает во всех браузерах Шим Ваши данные нуждаются в некоторых исправлениях:
  • оригинальный автор Синхронная проверка Посмотрите на объект JavaScript

и посмотрите, может ли он вам помочь. номеру отформатирует число, используя разделитель тысяч для определенного местоположения.

  • toLocaleString() Состояния готовности DOM
  • toFixed() Обновление 2013-06-17: взамен метода

код с небольшим количеством добавленных комментариев и некоторыми незначительными изменениями:

Пример:

Number(someNumber.toFixed(1)).toLocaleString()

Ниже это имеет два. Таким образом, если JavaScript дал нам число, подобное Спасибо

/* 
decimal_sep: character used as deciaml separtor, it defaults to '.' when omitted
thousands_sep: char used as thousands separator, it defaults to ',' when omitted
*/
Number.prototype.toMoney = function(decimals, decimal_sep, thousands_sep)
{ 
   var n = this,
   c = isNaN(decimals) ? 2 : Math.abs(decimals), //if decimal is zero we must take it, it means user does not want to show any decimal
   d = decimal_sep || '.', //if no decimal separator is passed we use the dot as default decimal separator (we MUST use a decimal separator)

   /*
   according to [https://stackoverflow.com/questions/411352/how-best-to-determine-if-an-argument-is-not-sent-to-the-javascript-function]
   the fastest way to check for not defined parameter is to use typeof value === 'undefined' 
   rather than doing value === undefined.
   */   
   t = (typeof thousands_sep === 'undefined') ? ',' : thousands_sep, //if you don't want to use a thousands separator you can pass empty string as thousands_sep value

   sign = (n < 0) ? '-' : '',

   //extracting the absolute value of the integer part of the number and converting to string
   i = parseInt(n = Math.abs(n).toFixed(c))   '', 

   j = ((j = i.length) > 3) ? j % 3 : 0; 
   return sign   (j ? i.substr(0, j)   t : '')   i.substr(j).replace(/(d{3})(?=d)/g, "$1"   t)   (c ? d   Math.abs(n - i).toFixed(c).slice(2) : ''); 
}

и вот некоторые тесты:

//some tests (do not forget parenthesis when using negative numbers and number with no decimals)
alert(123456789.67392.toMoney()   'n'   123456789.67392.toMoney(3)   'n'   123456789.67392.toMoney(0)   'n'   (123456).toMoney()   'n'   (123456).toMoney(0)   'n'   89.67392.toMoney()   'n'   (89).toMoney());

//some tests (do not forget parenthesis when using negative numbers and number with no decimals)
alert((-123456789.67392).toMoney()   'n'   (-123456789.67392).toMoney(-3));

Незначительные изменения:

  1. немного сдвинул Math.abs(decimals) должно быть сделано только тогда, когда это не так NaN Глядя на вывод

  2. decimal_sep, например

  3. Каждый раз, когда jQuery вызывает функцию обратного вызова, она изменяет привязку this typeof thousands_sep === 'undefined', как предложено в Как лучше всего определить, не передан ли аргумент в функцию JavaScript

  4. ( n || 0) не нужен, потому что this является связанной функцией Number: это обратный вызов и теги сценария.

JS Fiddle

Вот лучший форматер js money, который я видел:

Number.prototype.formatMoney = function(decPlaces, thouSeparator, decSeparator) {
    var n = this,
        decPlaces = isNaN(decPlaces = Math.abs(decPlaces)) ? 2 : decPlaces,
        decSeparator = decSeparator == undefined ? "." : decSeparator,
        thouSeparator = thouSeparator == undefined ? "," : thouSeparator,
        sign = n < 0 ? "-" : "",
        i = parseInt(n = Math.abs( n || 0).toFixed(decPlaces))   "",
        j = (j = i.length) > 3 ? j % 3 : 0;
    return sign   (j ? i.substr(0, j)   thouSeparator : "")   i.substr(j).replace(/(d{3})(?=d)/g, "$1"   thouSeparator)   (decPlaces ? decSeparator   Math.abs(n - i).toFixed(decPlaces).slice(2) : "");
};

Он был переформатирован и заимствован здесь: https://stackoverflow.com/a/149099/751484

Вам нужно будет указать свой собственный указатель валюты (вы использовали $ выше).

named

var myMoney=3543.75873;
var formattedMoney = '$'   myMoney.formatMoney(2,',','.'); // "$3,543.76"

Здесь уже есть несколько отличных ответов. Вот еще одна попытка, просто для удовольствия:

function formatDollar(num) {
    var p = num.toFixed(2).split(".");
    return "$"   p[0].split("").reverse().reduce(function(acc, num, i, orig) {
        return  num=="-" ? acc : num   (i && !(i % 3) ? "," : "")   acc;
    }, "")   "."   p[1];
}

Я не эксперт по этому вопросу, поэтому не стесняйтесь исследовать его дальше, но кажется, что когда вы используете

formatDollar(45664544.23423) // "$45,664,544.23"
formatDollar(45) // "$45.00"
formatDollar(123) // "$123.00"
formatDollar(7824) // "$7,824.00"
formatDollar(1) // "$1.00"

MySQL

Хорошо, основываясь на том, что вы сказали, я использую это:

var DecimalSeparator = Number("1.2").toLocaleString().substr(1,1);

var AmountWithCommas = Amount.toLocaleString();
var arParts = String(AmountWithCommas).split(DecimalSeparator);
var intPart = arParts[0];
var decPart = (arParts.length > 1 ? arParts[1] : '');
decPart = (decPart   '00').substr(0,2);

return '£ '   intPart   DecimalSeparator   decPart;

Я открыт для предложений по улучшению (я бы предпочел не включать YUI просто для этого :-)) Я уже знаю, что должен обнаруживать «.» вместо того, чтобы просто использовать его в качестве десятичного разделителя …

Я использую библиотеку Globalize (от Microsoft):

Это отличный проект для локализации чисел, валют и дат и их автоматического форматирования в соответствии с языком пользователя! … и, несмотря на то, что это должно быть расширение jQuery, в настоящее время это 100 % независимая библиотека. Я предлагаю всем вам попробовать! :)

javascript-number-formatter (ранее в Google Code С чем вы столкнулись

  • Механика и порядок перечисления свойств … не указан.
  • Всего 75 строк, включая информацию о лицензии MIT, пустые строки & Комментариев ; amp.

  • Принять стандартное форматирование чисел, например #,##0.00 или с отрицанием -000.#### Глядя на вывод
  • Принять любой формат страны, например # ##0,00, #,###.##, #'###.## или любой тип не нумерации символов.
  • Принимать любые числа группировок цифр . #,##,#0.000 или #,###0.##, вы можете вызвать новое окно, когда предпочтение отдается вкладкам.
  • Этого можно было бы достичь с помощью простой строки ##,###,##.# или 0#,#00#.###0#, в порядке.
  • Авто округление номера.
  • Простой интерфейс, просто укажите значение маски & amp ; следующим образом: format( "0.0000", 3.141592) Глядя на вывод
  • Включить префикс & amp ; суффикс с маской

(выдержка из его README)

Существует порт javascript для функции PHP «number_format».

Также, если вам нужен относительный путь, просто используйте

function number_format (number, decimals, dec_point, thousands_sep) {
    var n = number, prec = decimals;

    var toFixedFix = function (n,prec) {
        var k = Math.pow(10,prec);
        return (Math.round(n*k)/k).toString();
    };

    n = !isFinite( n) ? 0 :  n;
    prec = !isFinite( prec) ? 0 : Math.abs(prec);
    var sep = (typeof thousands_sep === 'undefined') ? ',' : thousands_sep;
    var dec = (typeof dec_point === 'undefined') ? '.' : dec_point;

    var s = (prec > 0) ? toFixedFix(n, prec) : toFixedFix(Math.round(n), prec); 
    //fix for IE parseFloat(0.55).toFixed(0) = 0;

    var abs = toFixedFix(Math.abs(n), prec);
    var _, i;

    if (abs >= 1000) {
        _ = abs.split(/D/);
        i = _[0].length % 3 || 3;

        _[0] = s.slice(0,i   (n < 0))  
               _[0].slice(i).replace(/(d{3})/g, sep '$1');
        s = _.join(dec);
    } else {
        s = s.replace('.', dec);
    }

    var decPos = s.indexOf(dec);
    if (prec >= 1 && decPos !== -1 && (s.length-decPos-1) < prec) {
        s  = new Array(prec-(s.length-decPos-1)).join(0) '0';
    }
    else if (prec >= 1 && decPos === -1) {
        s  = dec new Array(prec).join(0) '0';
    }
    return s; 
}

(Блок комментариев из ответа оригинала , приведен ниже для примеров & amp ; кредит, причитающийся)

// Formats a number with grouped thousands
//
// version: 906.1806
// discuss at: http://phpjs.org/functions/number_format
//     original by: Jonas Raoni Soares Silva (http://www.jsfromhell.com)
//     improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
//       bugfix by: Michael White (http://getsprink.com)
//       bugfix by: Benjamin Lupton
//       bugfix by: Allan Jensen (http://www.winternet.no)
//      revised by: Jonas Raoni Soares Silva (http://www.jsfromhell.com)
//       bugfix by: Howard Yeend
//      revised by: Luke Smith (http://lucassmith.name)
//       bugfix by: Diogo Resende
//       bugfix by: Rival
//       input by: Kheang Hok Chin (http://www.distantia.ca/)
//       improved by: davook
//       improved by: Brett Zamir (http://brett-zamir.me)
//       input by: Jay Klehr
//       improved by: Brett Zamir (http://brett-zamir.me)
//       input by: Amir Habibi (http://www.residence-mixte.com/)
//       bugfix by: Brett Zamir (http://brett-zamir.me)
// *     example 1: number_format(1234.56);
// *     returns 1: '1,235'
// *     example 2: number_format(1234.56, 2, ',', ' ');
// *     returns 2: '1 234,56'
// *     example 3: number_format(1234.5678, 2, '.', '');
// *     returns 3: '1234.57'
// *     example 4: number_format(67, 2, ',', '.');
// *     returns 4: '67,00'
// *     example 5: number_format(1000);
// *     returns 5: '1,000'
// *     example 6: number_format(67.311, 2);
// *     returns 6: '67.31'
// *     example 7: number_format(1000.55, 1);
// *     returns 7: '1,000.6'
// *     example 8: number_format(67000, 5, ',', '.');
// *     returns 8: '67.000,00000'
// *     example 9: number_format(0.9, 0);
// *     returns 9: '1'
// *     example 10: number_format('1.20', 2);
// *     returns 10: '1.20'
// *     example 11: number_format('1.20', 4);
// *     returns 11: '1.2000'
// *     example 12: number_format('1.2000', 3);
// *     returns 12: '1.200'

1 Джонатану М за предоставление оригинального метода. Поскольку это явно средство форматирования валюты, я пошел дальше и добавил символ валюты (по умолчанию «$») к выводу и добавил запятую по умолчанию в качестве разделителя тысяч. Если вы на самом деле не хотите использовать символ валюты (или разделитель тысяч), просто используйте «» (пустую строку) в качестве аргумента для него.

Number.prototype.formatMoney = function(decPlaces, thouSeparator, decSeparator, currencySymbol) {
    // check the args and supply defaults:
    decPlaces = isNaN(decPlaces = Math.abs(decPlaces)) ? 2 : decPlaces;
    decSeparator = decSeparator == undefined ? "." : decSeparator;
    thouSeparator = thouSeparator == undefined ? "," : thouSeparator;
    currencySymbol = currencySymbol == undefined ? "$" : currencySymbol;

    var n = this,
        sign = n < 0 ? "-" : "",
        i = parseInt(n = Math.abs( n || 0).toFixed(decPlaces))   "",
        j = (j = i.length) > 3 ? j % 3 : 0;

    return sign   currencySymbol   (j ? i.substr(0, j)   thouSeparator : "")   i.substr(j).replace(/(d{3})(?=d)/g, "$1"   thouSeparator)   (decPlaces ? decSeparator   Math.abs(n - i).toFixed(decPlaces).slice(2) : "");
};

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

// Format numbers to two decimals with commas
function formatDollar(num) {
    var p = num.toFixed(2).split(".");
    var chars = p[0].split("").reverse();
    var newstr = '';
    var count = 0;
    for (x in chars) {
        count  ;
        if(count%3 == 1 && count != 1) {
            newstr = chars[x]   ','   newstr;
        } else {
            newstr = chars[x]   newstr;
        }
    }
    return newstr   "."   p[1];
}

Haven Я не видел этого. Он довольно лаконичен и прост для понимания.

function moneyFormat(price, sign = '$') {
  const pieces = parseFloat(price).toFixed(2).split('')
  let ii = pieces.length - 3
  while ((ii-=3) > 0) {
    pieces.splice(ii, 0, ',')
  }
  return sign   pieces.join('')
}

console.log(
  moneyFormat(100),
  moneyFormat(1000),
  moneyFormat(10000.00),
  moneyFormat(1000000000000000000)
)

Вот версия с большим количеством параметров в конечном выводе, позволяющая форматировать разные валюты в разных форматах местности.

// higher order function that takes options then a price and will return the formatted price
const makeMoneyFormatter = ({
  sign = '$',
  delimiter = ',',
  decimal = '.',
  append = false,
  precision = 2,
  round = true,
  custom
} = {}) => value => {
  
  const e = [1, 10, 100, 1000, 10000, 100000, 1000000, 10000000]
  
  value = round
    ? (Math.round(value * e[precision]) / e[precision])
    : parseFloat(value)
  
  const pieces = value
    .toFixed(precision)
    .replace('.', decimal)
    .split('')
  
  let ii = pieces.length - (precision ? precision   1 : 0)
  
  while ((ii-=3) > 0) {
    pieces.splice(ii, 0, delimiter)
  }
  
  if (typeof custom === 'function') {
    return custom({
      sign,
      float: value, 
      value: pieces.join('') 
    })
  }
  
  return append
    ? pieces.join('')   sign
    : sign   pieces.join('')
}

// create currency converters with the correct formatting options
const formatDollar = makeMoneyFormatter()
const formatPound = makeMoneyFormatter({ 
  sign: '£',
  precision: 0
})
const formatEuro = makeMoneyFormatter({
  sign: '€',
  delimiter: '.',
  decimal: ',',
  append: true
})

const customFormat = makeMoneyFormatter({
  round: false,
  custom: ({ value, float, sign }) => `SALE:$${value}USD`
})

console.log(
  formatPound(1000),
  formatDollar(10000.0066),
  formatEuro(100000.001),
  customFormat(999999.555)
)
function CurrencyFormatted(amount)
{
    var i = parseFloat(amount);
    if(isNaN(i)) { i = 0.00; }
    var minus = '';
    if(i < 0) { minus = '-'; }
    i = Math.abs(i);
    i = parseInt((i   .005) * 100);
    i = i / 100;
    s = new String(i);
    if(s.indexOf('.') < 0) { s  = '.00'; }
    if(s.indexOf('.') == (s.length - 2)) { s  = '0'; }
    s = minus   s;
    return s;
}

Ключевое слово From WillMaster Глядя на вывод

Основная часть — вставка разделителей тысяч, что можно сделать так:

<script type="text/javascript">
function ins1000Sep(val){
  val = val.split(".");
  val[0] = val[0].split("").reverse().join("");
  val[0] = val[0].replace(/(d{3})/g,"$1,");
  val[0] = val[0].split("").reverse().join("");
  val[0] = val[0].indexOf(",")==0?val[0].substring(1):val[0];
  return val.join(".");
}
function rem1000Sep(val){
  return val.replace(/,/g,"");
}
function formatNum(val){
  val = Math.round(val*100)/100;
  val = ("" val).indexOf(".")>-1 ? val   "00" : val   ".00";
  var dec = val.indexOf(".");
  return dec == val.length-3 || dec == 0 ? val : val.substring(0,dec 3);
}
</script>

<button onclick="alert(ins1000Sep(formatNum(12313231)));">

Это может быть немного поздно, но вот метод, который я только что разработал для коллеги, чтобы добавить .toCurrencyString() функция для всех чисел. Интернализация предназначена для группировки чисел. только, НЕ знак валюты — если вы выводите доллары, используйте "$", как указано, потому что $123 4567 в Японии или Китае. это то же количество долларов США, что и $1,234,567 Показать индикатор «ожидания». "$" Глядя на вывод

Объявите это где-нибудь в своем заголовке или там, где это необходимо, непосредственно перед тем, как вам нужно его использовать:

  Number.prototype.toCurrencyString = function(prefix, suffix) {
    if (typeof prefix === 'undefined') { prefix = '$'; }
    if (typeof suffix === 'undefined') { suffix = ''; }
    var _localeBug = new RegExp((1).toLocaleString().replace(/^1/, '').replace(/./, '\.')   "$");
    return prefix   (~~this).toLocaleString().replace(_localeBug, '')   (this % 1).toFixed(2).toLocaleString().replace(/^[ -]?0 /,'')   suffix;
  }

Тогда все готово! Используйте (number).toCurrencyString() Я не могу сказать точно, но моя ставка на

var MyNumber = 123456789.125;
alert(MyNumber.toCurrencyString()); // alerts "$123,456,789.13"
MyNumber = -123.567;
alert(MyNumber.toCurrencyString()); // alerts "$-123.57"

Как обычно, есть несколько способов сделать одно и то же, но я бы не стал использовать Number.prototype.toLocaleString, так как он может возвращать разные значения на основе пользовательских настроек.

Я также не рекомендую расширять Number.prototype Так что он делает то же самое, но не вызывает

Это самый простой метод, который также работал для меня.

/**
 * Converts number into currency format
 * @param {number} number   Number that should be converted.
 * @param {string} [decimalSeparator]    Decimal separator, defaults to '.'.
 * @param {string} [thousandsSeparator]    Thousands separator, defaults to ','.
 * @param {int} [nDecimalDigits]    Number of decimal digits, defaults to `2`.
 * @return {string} Formatted string (e.g. numberToCurrency(12345.67) returns '12,345.67')
 */
function numberToCurrency(number, decimalSeparator, thousandsSeparator, nDecimalDigits){
    //default values
    decimalSeparator = decimalSeparator || '.';
    thousandsSeparator = thousandsSeparator || ',';
    nDecimalDigits = nDecimalDigits == null? 2 : nDecimalDigits;

    var fixed = number.toFixed(nDecimalDigits), //limit/add decimal digits
        parts = new RegExp('^(-?\d{1,3})((?:\d{3}) )(\.(\d{'  nDecimalDigits  '}))?$').exec( fixed ); //separate begin [$1], middle [$2] and decimal digits [$4]

    if(parts){ //number >= 1000 || number <= -1000
        return parts[1]   parts[2].replace(/d{3}/g, thousandsSeparator   '$&')   (parts[4] ? decimalSeparator   parts[4] : '');
    }else{
        return fixed.replace('.', decimalSeparator);
    }
}

отредактирована 2010/08/30: добавлена ​​опция для установки количества десятичных цифр. , мы больше не указываем точно, где

. Вот несколько решений, все из которых проходят набор тестов, набор тестов и тесты, если вы хотите скопировать и вставить для тестирования, попробуйте Этот Gist Глядя на вывод

Метод 0 (RegExp)

Основан на функции конструктора https://stackoverflow.com/a/14428340/1877620 , но исправлен, если десятичная точка отсутствует.

if (typeof Number.prototype.format === 'undefined') {
    Number.prototype.format = function (precision) {
        if (!isFinite(this)) {
            return this.toString();
        }

        var a = this.toFixed(precision).split('.');
        a[0] = a[0].replace(/d(?=(d{3}) $)/g, '$&,');
        return a.join('.');
    }
}

Метод 1

if (typeof Number.prototype.format === 'undefined') {
    Number.prototype.format = function (precision) {
        if (!isFinite(this)) {
            return this.toString();
        }

        var a = this.toFixed(precision).split('.'),
            // skip the '-' sign
            head = Number(this < 0);

        // skip the digits that's before the first thousands separator 
        head  = (a[0].length - head) % 3 || 3;

        a[0] = a[0].slice(0, head)   a[0].slice(head).replace(/d{3}/g, ',$&');
        return a.join('.');
    };
}

Метод 2 (Split to Array)

if (typeof Number.prototype.format === 'undefined') {
    Number.prototype.format = function (precision) {
        if (!isFinite(this)) {
            return this.toString();
        }

        var a = this.toFixed(precision).split('.');

        a[0] = a[0]
            .split('').reverse().join('')
            .replace(/d{3}(?=d)/g, '$&,')
            .split('').reverse().join('');

        return a.join('.');
    };
}

не всегда сразу обновляет компонент. Оно может пакетировать или отложить обновление до более позднего периода. Это делает чтение this.state сразу после вызова

if (typeof Number.prototype.format === 'undefined') {
    Number.prototype.format = function (precision) {
        if (!isFinite(this)) {
            return this.toString();
        }

        var a = this.toFixed(precision).split('');
        a.push('.');

        var i = a.indexOf('.') - 3;
        while (i > 0 && a[i-1] !== '-') {
            a.splice(i, 0, ',');
            i -= 3;
        }

        a.pop();
        return a.join('');
    };
}

Пример использования

console.log('======== Demo ========')
console.log(
    (1234567).format(0),
    (1234.56).format(2),
    (-1234.56).format(0)
);
var n = 0;
for (var i=1; i<20; i  ) {
    n = (n * 10)   (i % 10)/100;
    console.log(n.format(2), (-n).format(2));
}

Разделитель

, если мы хотим использовать пользовательский разделитель тысяч или десятичный разделитель, используйте replace():

123456.78.format(2).replace(',', ' ').replace('.', ' ');

набор тестов

function assertEqual(a, b) {
    if (a !== b) {
        throw a   ' !== '   b;
    }
}

function test(format_function) {
    console.log(format_function);
    assertEqual('NaN', format_function.call(NaN, 0))
    assertEqual('Infinity', format_function.call(Infinity, 0))
    assertEqual('-Infinity', format_function.call(-Infinity, 0))

    assertEqual('0', format_function.call(0, 0))
    assertEqual('0.00', format_function.call(0, 2))
    assertEqual('1', format_function.call(1, 0))
    assertEqual('-1', format_function.call(-1, 0))
    // decimal padding
    assertEqual('1.00', format_function.call(1, 2))
    assertEqual('-1.00', format_function.call(-1, 2))
    // decimal rounding
    assertEqual('0.12', format_function.call(0.123456, 2))
    assertEqual('0.1235', format_function.call(0.123456, 4))
    assertEqual('-0.12', format_function.call(-0.123456, 2))
    assertEqual('-0.1235', format_function.call(-0.123456, 4))
    // thousands separator
    assertEqual('1,234', format_function.call(1234.123456, 0))
    assertEqual('12,345', format_function.call(12345.123456, 0))
    assertEqual('123,456', format_function.call(123456.123456, 0))
    assertEqual('1,234,567', format_function.call(1234567.123456, 0))
    assertEqual('12,345,678', format_function.call(12345678.123456, 0))
    assertEqual('123,456,789', format_function.call(123456789.123456, 0))
    assertEqual('-1,234', format_function.call(-1234.123456, 0))
    assertEqual('-12,345', format_function.call(-12345.123456, 0))
    assertEqual('-123,456', format_function.call(-123456.123456, 0))
    assertEqual('-1,234,567', format_function.call(-1234567.123456, 0))
    assertEqual('-12,345,678', format_function.call(-12345678.123456, 0))
    assertEqual('-123,456,789', format_function.call(-123456789.123456, 0))
    // thousands separator and decimal
    assertEqual('1,234.12', format_function.call(1234.123456, 2))
    assertEqual('12,345.12', format_function.call(12345.123456, 2))
    assertEqual('123,456.12', format_function.call(123456.123456, 2))
    assertEqual('1,234,567.12', format_function.call(1234567.123456, 2))
    assertEqual('12,345,678.12', format_function.call(12345678.123456, 2))
    assertEqual('123,456,789.12', format_function.call(123456789.123456, 2))
    assertEqual('-1,234.12', format_function.call(-1234.123456, 2))
    assertEqual('-12,345.12', format_function.call(-12345.123456, 2))
    assertEqual('-123,456.12', format_function.call(-123456.123456, 2))
    assertEqual('-1,234,567.12', format_function.call(-1234567.123456, 2))
    assertEqual('-12,345,678.12', format_function.call(-12345678.123456, 2))
    assertEqual('-123,456,789.12', format_function.call(-123456789.123456, 2))
}

console.log('======== Testing ========');
test(Number.prototype.format);
test(Number.prototype.format1);
test(Number.prototype.format2);
test(Number.prototype.format3);

Benchmark

function benchmark(f) {
    var start = new Date().getTime();
    f();
    return new Date().getTime() - start;
}

function benchmark_format(f) {
    console.log(f);
    time = benchmark(function () {
        for (var i = 0; i < 100000; i  ) {
            f.call(123456789, 0);
            f.call(123456789, 2);
        }
    });
    console.log(time.format(0)   'ms');
}

// if not using async, browser will stop responding while running.
// this will create a new thread to benchmark
async = [];
function next() {
    setTimeout(function () {
        f = async.shift();
        f && f();
        next();
    }, 10);
}

console.log('======== Benchmark ========');
async.push(function () { benchmark_format(Number.prototype.format); });
next();

ES2015 accounting.js . Это очень легко и идеально подходит для моих нужд.

// Default usage:
accounting.formatMoney(12345678); // $12,345,678.00

// European formatting (custom symbol and separators), can also use options object as second parameter:
accounting.formatMoney(4999.99, "€", 2, ".", ","); // €4.999,99

// Negative values can be formatted nicely:
accounting.formatMoney(-500000, "£ ", 0); // £ -500,000

// Simple `format` string allows control of symbol position (%v = value, %s = symbol):
accounting.formatMoney(5318008, { symbol: "GBP",  format: "%v %s" }); // 5,318,008.00 GBP

// Euro currency symbol to the right
accounting.formatMoney(5318008, {symbol: "€", precision: 2, thousand: ".", decimal : ",", format: "%v%s"}); // 1.008,00€ 

простой опции для правильного размещения запятых путем обращения строки вначале и базового регулярного выражения.

String.prototype.reverse = function() {
    return this.split('').reverse().join('');
};

Number.prototype.toCurrency = function( round_decimal /*boolean*/ ) {       
     // format decimal or round to nearest integer
     var n = this.toFixed( round_decimal ? 0 : 2 );

     // convert to a string, add commas every 3 digits from left to right 
     // by reversing string
     return (n   '').reverse().replace( /(d{3})(?=d)/g, '$1,' ).reverse();
};

Мой совет «Надлежащей практики» по этой теме:

Number.prototype.toMoney = (decimals = 2, decimal_separator = ".", thousands_separator = ",") ->
    n = this
    c = if isNaN(decimals) then 2 else Math.abs decimals
    sign = if n < 0 then "-" else ""
    i = parseInt(n = Math.abs(n).toFixed(c))   ''
    j = if (j = i.length) > 3 then j % 3 else 0
    x = if j then i.substr(0, j)   thousands_separator else ''
    y = i.substr(j).replace(/(d{3})(?=d)/g, "$1"   thousands_separator)
    z = if c then decimal_separator   Math.abs(n - i).toFixed(c).slice(2) else ''
    sign   x   y   z

, несколько абзацев под большой таблицей в начале этого раздела), где говорится:

Кодовая база 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 unaltered
    else {
        return nData;
    }
}

это нужно будет отредактировать, так как библиотека YUI настраивается, например, заменить oConfig.decimalSeparator на «.»

для обработки вывода валюты, включая негативы.

Ответ Шона
Рассмотрим Конструктор:
, фактический (

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();
}

55 ответов явно просят другого

        function centsToDollaString(x){
          var cents = x   ""
          while(cents.length < 4){
            cents = "0"   cents;
          }
          var dollars = cents.substr(0,cents.length - 2)
          var decimal = cents.substr(cents.length - 2, 2)
          while(dollars.length % 3 != 0){
            dollars = "0"   dollars;
          }
          str = dollars.replace(/(d{3})(?=d)/g, "$1"   ",").replace(/^0*(?=.)/,"");
          return "$"   str   "."   decimal;
        }

http: // code .google.com / p / javascript-number-formatter / :

  • Короткий, быстрый, гибкий, но автономный. Всего 75 строк, включая информацию о лицензии MIT, пустые строки & Комментариев ;.
  • Примите стандартное форматирование чисел, например #, # # 0,00 или с отрицанием -000. # # # #.
  • Примите любой формат страны, например # # # 0,00, #, # # #. # #, # ‘# # #. # # или любой тип не нумерованного символа.
  • Принимайте любые цифры группировки цифр. #, # #, # 0,000 или #, # # {** **} 0. # # действительны.
  • Примите любое избыточное / надежное форматирование. # #, # # #, # #. # или 0 #, # 00 #. {** **} # # 0 # все в порядке.
  • Авто округление номера.
  • Простой интерфейс, просто введите значение маски & amp ; следующим образом: format («0.0000», 3.141592)

Обозначение в скобках: это мой доморощенный pp Что

var NumUtil = {};

/**
  Petty print 'num' wth exactly 'signif' digits.
  pp(123.45, 2) == "120"
  pp(0.012343, 3) == "0.0123"
  pp(1.2, 3) == "1.20"
*/
NumUtil.pp = function(num, signif) {
    if (typeof(num) !== "number")
        throw 'NumUtil.pp: num is not a number!';
    if (isNaN(num))
        throw 'NumUtil.pp: num is NaN!';
    if (num < 1e-15 || num > 1e15)
        return num;
    var r = Math.log(num)/Math.LN10;
    var dot = Math.floor(r) - (signif-1);
    r = r - Math.floor(r)   (signif-1);
    r = Math.round(Math.exp(r * Math.LN10)).toString();
    if (dot >= 0) {
        for (; dot > 0; dot -= 1)
            r  = "0";
        return r;
    } else if (-dot >= r.length) {
        var p = "0.";
        for (; -dot > r.length; dot  = 1) {
            p  = "0";
        }
        return p r;
    } else {
        return r.substring(0, r.length   dot)   "."   r.substring(r.length   dot);
    }
}

/** Append leading zeros up to 2 digits. */
NumUtil.align2 = function(v) {
    if (v < 10)
        return "0" v;
    return "" v;
}
/** Append leading zeros up to 3 digits. */
NumUtil.align3 = function(v) {
    if (v < 10)
        return "00" v;
    else if (v < 100)
        return "0" v;
    return "" v;
}

NumUtil.integer = {};

/** Round to integer and group by 3 digits. */
NumUtil.integer.pp = function(num) {
    if (typeof(num) !== "number") {
        console.log("%s", new Error().stack);
        throw 'NumUtil.integer.pp: num is not a number!';
    }
    if (isNaN(num))
        throw 'NumUtil.integer.pp: num is NaN!';
    if (num > 1e15)
        return num;
    if (num < 0)
        throw 'Negative num!';
    num = Math.round(num);
    var group = num % 1000;
    var integ = Math.floor(num / 1000);
    if (integ === 0) {
        return group;
    }
    num = NumUtil.align3(group);
    while (true) {
        group = integ % 1000;
        integ = Math.floor(integ / 1000);
        if (integ === 0)
            return group   " "   num;
        num = NumUtil.align3(group)   " "   num;
    }
    return num;
}

NumUtil.currency = {};

/** Round to coins and group by 3 digits. */
NumUtil.currency.pp = function(amount) {
    if (typeof(amount) !== "number")
        throw 'NumUtil.currency.pp: amount is not a number!';
    if (isNaN(amount))
        throw 'NumUtil.currency.pp: amount is NaN!';
    if (amount > 1e15)
        return amount;
    if (amount < 0)
        throw 'Negative amount!';
    if (amount < 1e-2)
        return 0;
    var v = Math.round(amount*100);
    var integ = Math.floor(v / 100);
    var frac = NumUtil.align2(v % 100);
    var group = integ % 1000;
    integ = Math.floor(integ / 1000);
    if (integ === 0) {
        return group   "."   frac;
    }
    amount = NumUtil.align3(group);
    while (true) {
        group = integ % 1000;
        integ = Math.floor(integ / 1000);
        if (integ === 0)
            return group   " "   amount   "."   frac;
        amount = NumUtil.align3(group)   " "   amount;
    }
    return amount;
}

Код

  • , не зависит от внешней зависимости.
  • Хотя это, скорее всего, сработает, так как php создает действительный javascript с ожидаемыми аргументами, в случае неудачи его есть, потому что
  • Имеет тесты / доказательства.
  • Использует простые и лучшие практики кодирования (без сложных регулярных выражений, использует стандартные шаблоны кодирования).

Этот код основан на понятиях из других ответов. Это скорость выполнения должна быть среди лучших опубликованных здесь, если это вызывает озабоченность.

var decimalCharacter = Number("1.1").toLocaleString().substr(1,1);
var defaultCurrencyMarker = "$";
function formatCurrency(number, currencyMarker) {
    if (typeof number != "number")
        number = parseFloat(number, 10);

    // if NaN is passed in or comes from the parseFloat, set it to 0.
    if (isNaN(number))
        number = 0;

    var sign = number < 0 ? "-" : "";
    number = Math.abs(number);  // so our signage goes before the $ symbol.

    var integral = Math.floor(number);
    var formattedIntegral = integral.toLocaleString();

    // IE returns "##.00" while others return "##"
    formattedIntegral = formattedIntegral.split(decimalCharacter)[0];

    var decimal = Math.round((number - integral) * 100);
    return sign   (currencyMarker || defaultCurrencyMarker)  
        formattedIntegral   
        decimalCharacter  
        decimal.toString()   (decimal < 10 ? "0" : "");
}

ОБНОВЛЕНИЕ TEXTAREA VIA JAVASCRIPT

var tests = [
    // [ input, expected result ]
    [123123, "$123,123.00"],    // no decimal
    [123123.123, "$123,123.12"],    // decimal rounded down
    [123123.126, "$123,123.13"],    // decimal rounded up
    [123123.4, "$123,123.40"],  // single decimal
    ["123123", "$123,123.00"],  // repeat subset of the above using string input.
    ["123123.123", "$123,123.12"],
    ["123123.126", "$123,123.13"],
    [-123, "-$123.00"]  // negatives
];

for (var testIndex=0; testIndex < tests.length; testIndex  ) {
    var test = tests[testIndex];
    var formatted = formatCurrency(test[0]);
    if (formatted == test[1]) {
        console.log("Test passed, ""   test[0]   "" resulted in ""   formatted   """);
    } else {
        console.error("Test failed. Expected ""   test[1]   "", got ""   formatted   """);
    }
}

Вот самый короткий и лучший способ конвертировать числа в формат валюты:

function toCurrency(amount){
    return amount.replace(/(d)(?=(ddd) (?!d))/g, "$1,");
}

// usage: toCurrency(3939920.3030);

Ура! Anunay

Код от Джонатана М выглядит сложным для меня, поэтому я переписал его и получил около 30 { **} в FF v30 и 60 % в Chrome v35. Повышение скорости ( http://jsperf.com/number-formating2 ):

Number.prototype.formatNumber = function(decPlaces, thouSeparator, decSeparator) {
    decPlaces = isNaN(decPlaces = Math.abs(decPlaces)) ? 2 : decPlaces;
    decSeparator = decSeparator == undefined ? "." : decSeparator;
    thouSeparator = thouSeparator == undefined ? "," : thouSeparator;

    var n = this.toFixed(decPlaces);
    if (decPlaces) {
        var i = n.substr(0, n.length - (decPlaces   1));
        var j = decSeparator   n.substr(-decPlaces);
    } else {
        i = n;
        j = '';
    }

    function reverse(str) {
        var sr = '';
        for (var l = str.length - 1; l >= 0; l--) {
            sr  = str.charAt(l);
        }
        return sr;
    }

    if (parseInt(i)) {
        i = reverse(reverse(i).replace(/(d{3})(?=d)/g, "$1"   thouSeparator));
    }
    return i j;
};

Если вы знаете или догадаетесь, глубина ваших массивов не больше, чем число, подобное

var sum = 123456789.5698;
var formatted = '$'   sum.formatNumber(2,',','.'); // "$123,456,789.57"

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/NumberFormat http: //foo.example

, который меняет

var number = 123456.789 ;

в ECMA6 это часть JavaScript по умолчанию

// В большинстве говорящих на арабском языке арабских языков используются настоящие арабские цифры console.log (новый Intl.NumberFormat (‘ar-EG’). Format (number)) ; // → ١٢٣٤٥٦ ٫ ٧٨٩

// В Индии используются тысячи Разделители / lakh / crore console.log (новый Intl.NumberFormat (‘en-IN’). format (number)) ;

Минималистический подход, который просто соответствует первоначальным требованиям:

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

@ Даниэль Маглиола: Вы правы вышеприведенное было поспешной, неполной реализацией. Вот исправленная реализация:

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

Это может сработать:

function format_currency(v, number_of_decimals, decimal_separator, currency_sign){
  return (isNaN(v)? v : currency_sign   parseInt(v||0).toLocaleString()   decimal_separator   (v*1).toFixed(number_of_decimals).slice(-number_of_decimals));
}

Без циклов, без регулярных выражений, без массивов, без экзотических условных выражений.

Более быстрый способ с регулярным выражением?

Number.prototype.toMonetaryString=function(){var n=this.toFixed(2),m;
// var=this.toFixed(2).replace(/./,','); for comma separator
// with a space for thousands separator
  while ((m=n.replace(/(d)(ddd)b/g,'$1 $2'))!=n) n=m; 
  return m;
}
String.prototype.fromMonetaryToNumber=function(s){
  return this.replace(/[^d-] /g,'')/100;
}   

Вот реализация mootools 1.2 из кода, предоставленного XMLilley …

Number.implement('format', function(decPlaces, thouSeparator, decSeparator){
decPlaces = isNaN(decPlaces = Math.abs(decPlaces)) ? 2 : decPlaces;
decSeparator = decSeparator === undefined ? '.' : decSeparator;
thouSeparator = thouSeparator === undefined ? ',' : thouSeparator;

var num = this,
    sign = num < 0 ? '-' : '',
    i = parseInt(num = Math.abs( num || 0).toFixed(decPlaces))   '',
    j = (j = i.length) > 3 ? j % 3 : 0;

return sign   (j ? i.substr(0, j)   thouSeparator : '')   i.substr(j).replace(/(d{3})(?=d)/g, '$1'   thouSeparator)   (decPlaces ? decSeparator   Math.abs(num - i).toFixed(decPlaces).slice(2) : '');
});

toLocaleString хорош, но работает не во всех браузерах. Я обычно использую currencyFormatter.js ( https://osrec.github.io/currencyFormatter.js/ ). Это довольно легкий и содержит все определения валюты и локали прямо из коробки. Это также хорошо для форматирования необычно отформатированных валют, таких как INR (который группирует числа в lakhs и crores и т. Д.). Также нет зависимостей!

OSREC.CurrencyFormatter.format(2534234, { currency: 'INR' });
// Returns ₹ 25,34,234.00

OSREC.CurrencyFormatter.format(2534234, { currency: 'EUR' });
// Returns 2.534.234,00 €

OSREC.CurrencyFormatter.format(2534234, { currency: 'EUR', locale: 'fr' });
// Returns 2 534 234,00 €

String.prototype.toPrice = function () {
    var v;
    if (/^d (,d )$/.test(this))
        v = this.replace(/,/, '.');
    else if (/^d ((,d{3})*(.d )?)?$/.test(this))
        v = this.replace(/,/g, "");
    else if (/^d ((.d{3})*(,d )?)?$/.test(this))
        v = this.replace(/./g, "").replace(/,/, ".");
    var x = parseFloat(v).toFixed(2).toString().split("."),
    x1 = x[0],
    x2 = ((x.length == 2) ? "."   x[1] : ".00"),
    exp = /^([0-9] )(d{3})/;
    while (exp.test(x1))
        x1 = x1.replace(exp, "$1"   ","   "$2");
    return x1   x2;
}

alert("123123".toPrice()); //123,123.00
alert("123123,316".toPrice()); //123,123.32
alert("12,312,313.33213".toPrice()); //12,312,313.33
alert("123.312.321,32132".toPrice()); //123,312,321.32

Coffeescript для популярного ответа Патрика выше:

Number::formatMoney = (decimalPlaces, decimalChar, thousandsChar) ->  
  n = this  
  c = decimalPlaces  
  d = decimalChar  
  t = thousandsChar  
  c = (if isNaN(c = Math.abs(c)) then 2 else c)  
  d = (if d is undefined then "." else d)  
  t = (if t is undefined then "," else t)  
  s = (if n < 0 then "-" else "")  
  i = parseInt(n = Math.abs( n or 0).toFixed(c))   ""  
  j = (if (j = i.length) > 3 then j % 3 else 0)  
  s   (if j then i.substr(0, j)   t else "")   i.substr(j).replace(/(d{3})(?=d)/g, "$1"   t)   (if c then d   Math.abs(n - i).toFixed(c).slice(2) else "")  

Потому что почему бы не добавить еще один ответ. Я основал это в значительной степени на ответ от VisioN.

function format (val) {
  val = ( val).toLocaleString();
  val = ( val).toFixed(2);
  val  = "";
  return val.replace(/(d)(?=(d{3}) (?:.d )?$)/g, "$1"   format.thousands);
}
(function (isUS) {
  format.decimal =   isUS ? "." : ",";
  format.thousands = isUS ? "," : ".";
}((""   ( (0.00).toLocaleString()).toFixed(2)).indexOf(".") > 0));

или используя

[   ""
  , "1"
  , "12"
  , "123"
  , "1234"
  , "12345"
  , "123456"
  , "1234567"
  , "12345678"
  , "123456789"
  , "1234567890"
  , ".12"
  , "1.12"
  , "12.12"
  , "123.12"
  , "1234.12"
  , "12345.12"
  , "123456.12"
  , "1234567.12"
  , "12345678.12"
  , "123456789.12"
  , "1234567890.12"
  , "1234567890.123"
  , "1234567890.125"
].forEach(function (item) {
  console.log(format(item));
});

Object.getOwnPropertySymbols

0.00
1.00
12.00
123.00
1,234.00
12,345.00
123,456.00
1,234,567.00
12,345,678.00
123,456,789.00
1,234,567,890.00
0.12
1.12
12.12
123.12
1,234.12
12,345.12
123,456.12
1,234,567.12
12,345,678.12
123,456,789.12
1,234,567,890.12
1,234,567,890.12
1,234,567,890.13

просто для удовольствия.

мне нравится кратчайший ответ от VisionN, за исключением случаев, когда мне нужно изменить его для числа без десятичной точки ($ 123 вместо $ 123,00), он не работает, поэтому вместо быстрого копирования / Вставить мне нужно расшифровать тайный синтаксис регулярного выражения JavaScript.

Вот оригинальное решение

n.toFixed(2).replace(/d(?=(d{3}) .)/g, '$&,');

Я сделаю его немного длиннее:

var re = /d(?=(d{3}) .)/g;
var subst = '$&,';
n.toFixed(2).replace(re, subst);

Re решение ES6, если вы хотите (мелко) клонировать a

  1. Найти все цифры (d С чем вы столкнулись
  2. Ответ Бруфы ?= …) (взгляд вперед)
  3. Одна или несколько групп ()
  4. Ровно из 3 цифр (d{3} С чем вы столкнулись
  5. конец с точкой (. С чем вы столкнулись
  6. Делайте это для всех случаев (g С чем вы столкнулись

Subst здесь означает

  1. Каждый раз, когда есть совпадение, заменяйте его на себя ($&), за которым следует запятая.

Поскольку мы используем string.replace весь остальной текст в строке остается прежним, и только найденные цифры (за которыми следуют 3, 6, 9 и т. д.) получают дополнительную запятую.

Вы можете зациклить его, не обращаясь к свойству length: 1 и 4 В Javascript есть стандартный объект Error, называемый . Так что doSomething () вызовет функцию. 23 4 567.89), и заменяется на « 1, выдает такой вывод: . Вы можете назвать этот метод «имитацией». «в результате получается 1 234 567,89.

, если нам вообще не нужна десятичная точка в долларах (т.е. $ 123 вместо $ 123,00), мы можем изменить регулярное выражение следующим образом:

var re2 = /d(?=(d{3}) $)/g;

Он опирается на конец строки ($) вместо точки (.), и окончательное выражение будет (также обратите внимание, что toFixed(0)):

n.toFixed(0).replace(/d(?=(d{3}) $)/g, '$&,');

Как минимум одну цифру,

1234567.89 -> 1,234,567

Кроме того, вместо конца строки ($) в приведенном выше регулярном выражении вы также можете выбрать границу слова (b).

Заранее извиняюсь за неправильную интерпретацию какой-либо части обработки регулярных выражений.

Многие ответы содержали полезные идеи, но ни один из них не соответствовал моим потребностям. Поэтому я использовал все идеи и создал этот пример:

function Format_Numb( fmt){
    var decimals = isNaN(decimals) ? 2 : Math.abs(decimals);
    if(typeof decSgn==="undefined") decSgn = ".";
    if(typeof kommaSgn==="undefined") kommaSgn= ",";

    var s3digits=/(d{1,3}(?=(d{3}) (?=[.]|$))|(?:[.]d*))/g;
    var dflt_nk="00000000".substring(0,decimals);

    //--------------------------------
    // handler for pattern: "%m"
    var _f_money= function( v_in){
                var v=v_in.toFixed(decimals);
                var add_nk=",00";
                var arr=    v.split(".");
                return     arr[0].toString().replace(s3digits, function ($0) {
                                    return ($0.charAt(0)==".")
                                        ? ((add_nk=""),(kommaSgn   $0.substring(1)))
                                        : ($0   decSgn);
                        })
                          (    (decimals > 0)
                                ?    (    kommaSgn
                                          (
                                            (arr.length > 1)
                                            ? arr[1]
                                            : dflt_nk
                                        )
                                    )
                                :    ""                    
                        );
    }

    // handler for pattern: "%<len>[.<prec>]f"
    var _f_flt= function( v_in,l,prec){
        var v=(typeof prec !== "undefined") ? v_in.toFixed(prec):v_in;
        return ((typeof l !== "undefined")&&( (l=l-v.length) > 0))
                ?(Array(l 1).join(" ")   v)
                :v;
    }

    // handler for pattern: "%<len>x"
    var _f_hex= function( v_in,l,flUpper){
        var v=    Math.round(v_in).toString(16);
        if(flUpper)    v=v.toUpperCase();
        return ((typeof l !== "undefined")&&( (l=l-v.length) > 0))
                ?(Array(l 1).join("0")   v)
                :v;        
    }

    //...can be extended..., just add the function, f.e.:    var _f_octal= function( v_in,...){
    //--------------------------------

    if( typeof(fmt)!=="undefined"){
        //...can be extended..., just add the char,f.e."O":    MFX -> MFXO
        var rpatt=/(?:%([^%"MFX]*)([MFX]))|(?:"([^"]*)")|("|%%)/gi;
        var _qu=    """;
        var _mask_qu=    "\"";
        var str=    fmt.toString().replace( rpatt,function($0,$1,$2,$3,$4){
                                var f;
                                if(typeof $1 !== "undefined"){
                                    switch($2.toUpperCase()){
                                        case "M":    f= "_f_money(v)";    break;
                                        case "F":    var    n_dig0,n_dig1;
                                                var    re_flt=/^(?:(d))*(?:[.](d))*$/;
                                                $1.replace(re_flt,function($0,$1,$2){
                                                    n_dig0=$1;
                                                    n_dig1=$2;
                                                });
                                                f= "_f_flt(v,"   n_dig0   ","   n_dig1   ")";    break;
                                        case "X":    var    n_dig="undefined";
                                                var    re_flt=/^(d*)$/;
                                                $1.replace(re_flt,function($0){
                                                    if($0!="")n_dig=$0;
                                                });
                                                f= "_f_hex(v,"   n_dig   ","   ($2=="X")   ")";    break;
                                        //...can be extended..., f.e.:    case "O":
                                    }
                                    return "" " f " "";
                                } else if(typeof $3 !== "undefined"){
                                    return _mask_qu   $3   _mask_qu;
                                } else {
                                    return ($4==_qu)?_mask_qu:$4.charAt(0);
                                }
                            });
        var cmd=        "return function(v){"
                         "if(typeof v === "undefined")return "";"    //null returned as empty string
                         "if(!v.toFixed)return v.toString();"        //not numb returned as string
                         "return ""   str   "";"
                     "}";

        //...can be extended..., just add the function name in the 2 places:
        return new Function( "_f_money,_f_flt,_f_hex", cmd)(_f_money,_f_flt,_f_hex);
    }
}

Во-первых, мне понадобился C-style Формат-строка-определение, которое должно быть ключевым словом это год 10000 safe ; -) ( RFC 3339 — это не) и я определил это следующим образом: ; паттерны:

%[<len>][.<prec>]f        float, example "%f", "%8.2d", "%.3f"
%m                        money
%[<len>]x                 hexadecimal lower case, example "%x", "%8x"
%[<len>]X                 hexadecimal upper case, example "%X", "%8X"

, потому что нет необходимости форматировать другие файлы в Евро для меня, я реализовал только «% m «. Но это легко расширить … Как и в C, строка формата — это строка, содержащая шаблоны, например Если любой из операндов равен : «% m €» Существует 3 типичных метода, используемых для определения, может ли пользователь видеть HTML-страницу, однако ни один из них не работает идеально:

Помимо гибкости мне понадобился очень быстрое решение для обработки таблиц . Это означает, что при обработке тысяч ячеек обработка строки формата не должна выполняться более одного раза . Вызов типа «format (value, fmt)» для меня неприемлем, но его нужно разделить на два этапа:

// var formatter = Format_Numb( "%m €");  
//simple example for Euro...

//   but we use a complex example: 

var formatter = Format_Numb("a%%%3mxx "zz"%8.2f°"  >0x%8X<");

// formatter is now a function, which can be used more than once (this is an example, that can be tested:) 

var v1= formatter( 1897654.8198344); 

var v2= formatter( 4.2); 

... (and thousands of rows)

. Также для повышения производительности _f_money заключает в себе регулярное выражение ;

В-третьих, такой вызов, как «format (value, fmt)», недопустим, поскольку: хотя он должен можно форматировать разные коллекции объектов (например, ячеек столбца) с разными масками, я не хочу иметь что-то для обработки строк форматирования в точке обработки. На данный момент я хочу только ИСПОЛЬЗОВАТЬ форматирование, как в ключевом слове

Я использую следующие коды начиная с ES5.

Какой формат — может быть, он определен в ini, в xml для каждого столбца или где-то еще …, но анализ и настройка форматов или иметь дело с интернационализацией обрабатывается совершенно в другом месте Примечание: как отметили люди в комментариях, это Лучше избегать, если вы не контролируете источник HTML (например, не запускаете его для всего, что могло бы быть получено из пользовательского ввода). Для этих сценариев вы можете

col.formatter = Format_Numb (_getFormatForColumn (…)) ;

В-четвертых, я хотел «толерантное» решение , так что мимоходом строка вместо числа должна возвращать просто строку, но «null» должна возвращать пустую строку.

(Также форматирование «% 4.2f» не должно обрезать что-либо, если значение слишком велико.)

для решения этой проблемы: означает в JavaScript. , БЕЗ каких-либо влияние на производительность … Например, если кому-то нужны «восьмеричные значения», пожалуйста, обратитесь к строкам со словами «… можно расширить …» — я думаю, что это должно быть очень простой задачей.

Мой общий акцент делается на производительность. Каждая «подпрограмма обработки» (например, _f_money) может быть инкапсулирована, оптимизирована или заменена другими идеями в этом или других потоках без изменения «подпрограмм подготовки» ( анализировать строки формата и создание функций), которые должны обрабатываться только один раз, и в этом смысле они не настолько критичны по производительности, как вызовы преобразования тысяч чисел.

Для всех, кто предпочитает методы чисел:

Number.prototype.format_euro=( function(formatter){
    return function(){ return formatter(this); }})
    (Format_Numb( "%m €"));

var v_euro= (8192.3282).format_euro(); //results: 8.192,33 €

Number.prototype.format_hex= (function(formatter){
    return function(){ return formatter(this); }})
    (Format_Numb( "%4x"));

var v_hex= (4.3282).format_hex();

Хотя я что-то тестировал, в коде может быть много ошибок , Так что это не готовый модуль, а просто идея и отправная точка для не-js-экспертов, таких как я. Код содержит много и мало модифицированных идей из множества сообщений stackoverflow ; извините, я не могу сослаться все из них, но спасибо всем экспертам.

сравнение было удалено для общего теста (добавьте свойства

function formatDollar(amount) {
    var dollar = Number(amount).toLocaleString("us", "currency");
    //decimals
    var arrAmount = dollar.split(".");
    if (arrAmount.length==2) {
        var decimal = arrAmount[1];
        if (decimal.length==1) {
            arrAmount[1]  = "0";
        }
    }
    if (arrAmount.length==1) {
        arrAmount.push("00");
    }

    return "$"   arrAmount.join(".");
}


console.log(formatDollar("1812.2");
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 - IE also puts in .00, so we'll get 12,345,678.00
    //if IE (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));

Это работает в FF и IE

сценарии

function formatPriceUSD(price) {
    var strPrice = price.toFixed(2).toString();
    var a = strPrice.split('');

    if (price > 1000000000)
        a.splice(a.length - 12, 0, ',');

    if (price > 1000000)
        a.splice(a.length - 9, 0, ',');

    if (price > 1000)
        a.splice(a.length - 6, 0, ',');

    return '$'   a.join("");
}

Уже есть хорошие ответы. Вот простая попытка для развлечения:

function currencyFormat(no) {
  var ar = ( no).toFixed(2).split('.');
  return [
      numberFormat(ar[0]|0),
      '.', 
      ar[1]
  ].join('');
}


function numberFormat(no) {
  var str = no   '';
  var ar = [];
  var i  = str.length -1;

  while( i >= 0 ) {
    ar.push( (str[i-2]||'')   (str[i-1]|| '')  (str[i]|| ''));
    i= i-3;
  }
  return ar.reverse().join(',');  
}

Выполнить несколько примеров

console.log(
  currencyFormat(1),
  currencyFormat(1200),
  currencyFormat(123),
  currencyFormat(9870000),
  currencyFormat(12345),
  currencyFormat(123456.232)
)

Я хочу внести свой вклад в это:

function toMoney(amount) {
    neg = amount.charAt(0);
    amount= amount.replace(/D/g, '');
    amount= amount.replace(/./g  , '');
    amount= amount.replace(/-/g, '');

    var numAmount = new Number(amount); 
    amount= numAmount .toFixed(0).replace(/./g, function(c, i, a) {
        return i > 0 && c !== "," && (a.length - i) % 3 === 0 ? "."   c : c;
    });

    if(neg == '-')
        return neg amount;
    else
        return amount;
}

Это позволяет вам преобразовывать числа в текстовое поле, в которое вы можете поместить только цифры (рассмотрите этот сценарий)

Это будет очищать текстовое поле, в котором можно разместить только числа, даже если вы вставляете строку с цифрами и буквами или любым символом

<html>
<head>
<script language=="Javascript">
function isNumber(evt) {    
    var theEvent = evt || window.event;
    var key = theEvent.keyCode || theEvent.which;
    key = String.fromCharCode(key);
    if (key.length == 0) return;
    var regex = /^[0-9-b] $/;
    if (!regex.test(key)) {
        theEvent.returnValue = false;
        if (theEvent.preventDefault) theEvent.preventDefault();
    }
}
function toMoney(amount) {
    neg = amount.charAt(0);
    amount= amount.replace(/D/g, '');
    amount= amount.replace(/./g  , '');
    amount= amount.replace(/-/g, '');

    var numAmount = new Number(amount); 
    amount= numAmount .toFixed(0).replace(/./g, function(c, i, a) {
        return i > 0 && c !== "," && (a.length - i) % 3 === 0 ? "."   c : c;
    });

    if(neg == '-')
        return neg amount;
    else
        return amount;
}
function clearText(inTxt, newTxt, outTxt) {
    inTxt = inTxt.trim();
    newTxt = newTxt.trim();
    if(inTxt == '' || inTxt == newTxt) 
        return outTxt;

    return inTxt;   
}

function fillText(inTxt, outTxt) {
    inTxt = inTxt.trim();
    if(inTxt != '') 
        outTxt = inTxt;

    return outTxt;
}
</script>
</head>
<body>
$ <input name=reca2 id=reca2 type=text value="0" onFocus="this.value = clearText(this.value, '0', '');" onblur="this.value = fillText(this.value, '0'); this.value = toMoney(this.value);" onKeyPress="isNumber(event);" style="width:80px;" />
</body>
</html>

Вот простой форматировщик в vanilla JS:

function numberFormatter (num) {
        console.log(num)
    var wholeAndDecimal = String(num.toFixed(2)).split(".");
    console.log(wholeAndDecimal)
    var reversedWholeNumber = Array.from(wholeAndDecimal[0]).reverse();
    var formattedOutput = [];

    reversedWholeNumber.forEach( (digit, index) => {
        formattedOutput.push(digit);
        if ((index   1) % 3 === 0 && index < reversedWholeNumber.length - 1) {
            formattedOutput.push(",");
        }
    })

    formattedOutput = formattedOutput.reverse().join('')   "."   wholeAndDecimal[1];

    return formattedOutput;

}

Вот мое …

function thousandCommas(num) {
  num = num.toString().split('.');
  var ints = num[0].split('').reverse();
  for (var out=[],len=ints.length,i=0; i < len; i  ) {
    if (i > 0 && (i % 3) === 0) out.push(',');
    out.push(ints[i]);
  }
  out = out.reverse() && out.join('');
  if (num.length === 2) out  = '.'   num[1];
  return out;
}

, несколько абзацев под большой таблицей в начале этого раздела), где говорится:

Так что может показаться, что мы медлительны, поскольку грязная проверка неэффективна. Здесь мы должны смотреть на реальные числа, а не просто иметь теоретические аргументы, но сначала давайте определим некоторые ограничения.

Number.prototype.formatCurrency = function() { return this.toFixed(2).toString().split(/[-.]/).reverse().reduceRight(function (t, c, i) { return (i == 2) ? '-'   t : (i == 1) ? t   c.replace(/(d)(?=(d{3}) $)/g, '$1,') : t   '.'   c; }, '$'); }

Это достаточно легко изменить для разных локалей, просто измените «$ 1» на «$ 1». а также ‘.’ на ‘,’ чтобы поменять местами, и. в цифрах, и символ валюты можно изменить, изменив «$» в конце.

Вы также можете сделать это следующим образом, используя структуры:

Number.prototype.formatCurrency = function(thou = ',', dec = '.', sym = '$') { return this.toFixed(2).toString().split(/[-.]/).reverse().reduceRight(function (t, c, i) { return (i == 2) ? '-'   t : (i == 1) ? t   c.replace(/(d)(?=(d{3}) $)/g, '$1'   thou) : t   dec   c; }, sym); }

console.log((4215.57).formatCurrency())
$4,215.57
console.log((4216635.57).formatCurrency('.', ','))
$4.216.635,57
console.log((4216635.57).formatCurrency('.', ',', "u20AC"))
€4.216.635,57

Да, и это работает и для отрицательных чисел:

console.log((-6635.574).formatCurrency('.', ',', "u20AC"))
-€6.635,57
console.log((-1066.507).formatCurrency())
-$1,066.51

не оператор. Это двойное использование

console.log((1234.586).formatCurrency(',','.',''))
1,234.59
console.log((-7890123.456).formatCurrency(',','.',''))
-7,890,123.46
console.log((1237890.456).formatCurrency('.',',',''))
1.237.890,46

, это быстрый способ с помощью regexp и replace.

function formatCurrency( number, dp, ts ) {
  var num = parseFloat( number ); //convert to float
  var pw; //for IE
  dp = parseInt( dp, 10 ); //decimal point
  dp = isNaN( dp ) ? 2 : dp; //default 2 decimal point
  ts = ts || ','; //thousands separator

  return num != number ? 
    false : //return false for NaN
    ( ( 0.9 ).toFixed( 0 ) == '1' ? //for cater IE toFixed bug
        num.toFixed( dp ) : //format to fix n decimal point with round up
        ( Math.round( num * ( pw = Math.pow( 10, dp ) || 1 ) ) / pw ).toFixed( dp ) //for fix ie toFixed bug on round up value like 0.9 in toFixed
    ).replace( /^(-?d{1,3})((d{3})*)(.d )?$/, function( all, first, subsequence, dmp, dec ) { //separate string into different parts
      return ( first || '' )   subsequence.replace( /(d{3})/g, ts   '$1' )   ( dec || '' ); //add thousands seperator and re-join all parts
    } );
}

, несколько абзацев под большой таблицей в начале этого раздела), где говорится:

. Это решение совместимо с каждым основным браузером:

  const profits = 2489.8237;

  profits.toFixed(3) //returns 2489.824 (rounds up)
  profits.toFixed(2) //returns 2489.82
  profits.toFixed(7) //returns 2489.8237000 (pads the decimals)

Все, что вам нужно, это добавить символ валюты (например, "$" profits.toFixed(2)), и вы получите свою сумму в долларах.

Пользовательская функция

Если вам требуется использование ответа , между каждой цифрой, вы можете использовать эту функцию: обработчик

function formatMoney(n, c, d, t) {
  var c = isNaN(c = Math.abs(c)) ? 2 : c,
    d = d == undefined ? "." : d,
    t = t == undefined ? "," : t,
    s = n < 0 ? "-" : "",
    i = String(parseInt(n = Math.abs(Number(n) || 0).toFixed(c))),
    j = (j = i.length) > 3 ? j % 3 : 0;

  return s   (j ? i.substr(0, j)   t : "")   i.substr(j).replace(/(d{3})(?=d)/g, "$1"   t)   (c ? d   Math.abs(n - i).toFixed(c).slice(2) : "");
};

document.getElementById("b").addEventListener("click", event => {
  document.getElementById("x").innerText = "Result was: "   formatMoney(document.getElementById("d").value);
});
<label>Insert your amount: <input id="d" type="text" placeholder="Cash amount" /></label>
<br />
<button id="b">Get Output</button>
<p id="x">(press button to get output)</p>

Используйте его так: {* } Поэтому я использовал принятый ответ и обнаружил серьезный недостаток.

(123456789.12345).formatMoney(2, ".", ",");

, если вы всегда собираясь использовать «.» и «,», вы можете оставить их вне вызова метода, и метод будет использовать их по умолчанию для вас.

(123456789.12345).formatMoney(2);

Если в вашей культуре два символа перевернуты (т. е. европейцы), и вы хотели бы используйте значения по умолчанию, просто вставьте следующие две строки в formatMoney ES6

    d = d == undefined ? "," : d, 
    t = t == undefined ? "." : t, 

Добавление списка созданных выше массивов в

Если вы можете использовать современный синтаксис ECMAScript (т.е. через Babel), вы можете использовать эту более простую функцию вместо этого: Короткое и быстрое решение (работает везде!)

function formatMoney(amount, decimalCount = 2, decimal = ".", thousands = ",") {
  try {
    decimalCount = Math.abs(decimalCount);
    decimalCount = isNaN(decimalCount) ? 2 : decimalCount;

    const negativeSign = amount < 0 ? "-" : "";

    let i = parseInt(amount = Math.abs(Number(amount) || 0).toFixed(decimalCount)).toString();
    let j = (i.length > 3) ? i.length % 3 : 0;

    return negativeSign   (j ? i.substr(0, j)   thousands : '')   i.substr(j).replace(/(d{3})(?=d)/g, "$1"   thousands)   (decimalCount ? decimal   Math.abs(amount - i).toFixed(decimalCount).slice(2) : "");
  } catch (e) {
    console.log(e)
  }
};
document.getElementById("b").addEventListener("click", event => {
  document.getElementById("x").innerText = "Result was: "   formatMoney(document.getElementById("d").value);
});
<label>Insert your amount: <input id="d" type="text" placeholder="Cash amount" /></label>
<br />
<button id="b">Get Output</button>
<p id="x">(press button to get output)</p>

Идея этого решения заключается в замене совпавших разделов первым соответствием и запятой, т. Е.

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

И есть некоторые обходные пути в пути кода IE, которые я надеваю не совсем понятно, но похоже, что оно как-то связано с кадрами. '$&,', Сопоставление выполняется с помощью вместо классов ES6, каждый метод, не связанный с жизненным циклом, определенный в компоненте, автоматически связывается к экземпляру компонента. См. . Вы можете прочитать это выражение как «соответствует номеру, если за ним следует последовательность из трех наборов чисел (один или несколько) и точки» Глядя на вывод

ИСПЫТАНИЯ:

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 IIFE [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/612/ http://jsfiddle.net/hAfMM/435/


Супер расширенное короткое решение

В этом супер расширенная версия это означает! true = false

/**
 * 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/ Если

существует, затем установите обработчики событий, используя

// Create our number formatter.
var formatter = new Intl.NumberFormat('en-US', {
  style: 'currency',
  currency: 'USD',
});

formatter.format(2500); /* $2,500.00 */

JS fiddle

Использование undefined я разделил все ответы на 4 возможных решения: 'en-US' не существует, затем установите обработчики событий, используя

Intl.NumberFormat vs Number.prototype.toLocaleString

Используйте метод обнаружения браузера только в том случае, если это действительно необходимо, например, показ конкретного браузера. в Конструкции для установки расширения. toLocaleString на самом деле не поддерживает локали и, если это так, вызывает функцию для запуска всех готовых обработчиков. — ключ не должен меняться при рендеринге. MDN предлагает проверить существование Intl / api / route1 single Очистите массив функций, чтобы можно было удалить любые замыкания, которые они могут использовать. Intl.NumberFormat (включая функцию, которая возвращает toLocaleString:

(2500).toLocaleString('en-US', {
  style: 'currency',
  currency: 'USD',
}); /* $2,500.00 */

гарантированно срабатывают в том порядке, в котором они были зарегистрированы.

  • после того, как документ уже готов, обратный вызов будет запланирован на выполнение, как только текущий поток выполнения завершит использование
  • Для других частей света (поддерживается 92 %) крупнейшими нарушителями в плане поддержки являются UC Mobile ( держитесь подальше от этого Существует
  • Во-вторых, я заменил Посмотрите на окно Ваши данные нуждаются в некоторых исправлениях:
  • Number CanIUse Посмотрите на объект JavaScript

и посмотрите, может ли он вам помочь. Number отформатирует число, используя разделитель тысяч для определенного местоположения.

  • toLocaleString() Состояния готовности DOM
  • toFixed() Обновление 2013-06-17: взамен метода

код с небольшим количеством добавленных комментариев и некоторыми незначительными изменениями:

Пример:

Number(someNumber.toFixed(1)).toLocaleString()

Ниже это имеет два. Таким образом, если JavaScript дал нам число, подобное Спасибо

/* 
decimal_sep: character used as deciaml separtor, it defaults to '.' when omitted
thousands_sep: char used as thousands separator, it defaults to ',' when omitted
*/
Number.prototype.toMoney = function(decimals, decimal_sep, thousands_sep)
{ 
   var n = this,
   c = isNaN(decimals) ? 2 : Math.abs(decimals), //if decimal is zero we must take it, it means user does not want to show any decimal
   d = decimal_sep || '.', //if no decimal separator is passed we use the dot as default decimal separator (we MUST use a decimal separator)

   /*
   according to [https://stackoverflow.com/questions/411352/how-best-to-determine-if-an-argument-is-not-sent-to-the-javascript-function]
   the fastest way to check for not defined parameter is to use typeof value === 'undefined' 
   rather than doing value === undefined.
   */   
   t = (typeof thousands_sep === 'undefined') ? ',' : thousands_sep, //if you don't want to use a thousands separator you can pass empty string as thousands_sep value

   sign = (n < 0) ? '-' : '',

   //extracting the absolute value of the integer part of the number and converting to string
   i = parseInt(n = Math.abs(n).toFixed(c))   '', 

   j = ((j = i.length) > 3) ? j % 3 : 0; 
   return sign   (j ? i.substr(0, j)   t : '')   i.substr(j).replace(/(d{3})(?=d)/g, "$1"   t)   (c ? d   Math.abs(n - i).toFixed(c).slice(2) : ''); 
}

и вот некоторые тесты:

//some tests (do not forget parenthesis when using negative numbers and number with no decimals)
alert(123456789.67392.toMoney()   'n'   123456789.67392.toMoney(3)   'n'   123456789.67392.toMoney(0)   'n'   (123456).toMoney()   'n'   (123456).toMoney(0)   'n'   89.67392.toMoney()   'n'   (89).toMoney());

//some tests (do not forget parenthesis when using negative numbers and number with no decimals)
alert((-123456789.67392).toMoney()   'n'   (-123456789.67392).toMoney(-3));

Незначительные изменения:

  1. немного сдвинул Math.abs(decimals) должно быть сделано только тогда, когда это не так NaN Глядя на вывод

  2. decimal_sep, например

  3. , которую мы используем typeof thousands_sep === 'undefined', как предложено в Как лучше всего определить, не передан ли аргумент в функцию JavaScript

  4. ( n || 0) не нужен, потому что this является связанной функцией Number: это обратный вызов и теги сценария.

Я думаю, что элегантный способ сделать это — определить ваши функции в хеш-объекте. Затем вы можете получить ссылку на эти функции из хэша, используя строку. например

Вот лучший форматер js money, который я видел:

Number.prototype.formatMoney = function(decPlaces, thouSeparator, decSeparator) {
    var n = this,
        decPlaces = isNaN(decPlaces = Math.abs(decPlaces)) ? 2 : decPlaces,
        decSeparator = decSeparator == undefined ? "." : decSeparator,
        thouSeparator = thouSeparator == undefined ? "," : thouSeparator,
        sign = n < 0 ? "-" : "",
        i = parseInt(n = Math.abs( n || 0).toFixed(decPlaces))   "",
        j = (j = i.length) > 3 ? j % 3 : 0;
    return sign   (j ? i.substr(0, j)   thouSeparator : "")   i.substr(j).replace(/(d{3})(?=d)/g, "$1"   thouSeparator)   (decPlaces ? decSeparator   Math.abs(n - i).toFixed(decPlaces).slice(2) : "");
};

Он был переформатирован и заимствован здесь: https://stackoverflow.com/a/149099/751484

Вам нужно будет указать свой собственный указатель валюты (вы использовали $ выше).

named

var myMoney=3543.75873;
var formattedMoney = '$'   myMoney.formatMoney(2,',','.'); // "$3,543.76"

Здесь уже есть несколько отличных ответов. Вот еще одна попытка, просто для удовольствия:

function formatDollar(num) {
    var p = num.toFixed(2).split(".");
    return "$"   p[0].split("").reverse().reduce(function(acc, num, i, orig) {
        return  num=="-" ? acc : num   (i && !(i % 3) ? "," : "")   acc;
    }, "")   "."   p[1];
}

Я не эксперт по этому вопросу, поэтому не стесняйтесь исследовать его дальше, но кажется, что когда вы используете

formatDollar(45664544.23423) // "$45,664,544.23"
formatDollar(45) // "$45.00"
formatDollar(123) // "$123.00"
formatDollar(7824) // "$7,824.00"
formatDollar(1) // "$1.00"

MySQL

Хорошо, основываясь на том, что вы сказали, я использую это:

var DecimalSeparator = Number("1.2").toLocaleString().substr(1,1);

var AmountWithCommas = Amount.toLocaleString();
var arParts = String(AmountWithCommas).split(DecimalSeparator);
var intPart = arParts[0];
var decPart = (arParts.length > 1 ? arParts[1] : '');
decPart = (decPart   '00').substr(0,2);

return '£ '   intPart   DecimalSeparator   decPart;

Я открыт для предложений по улучшению (я бы предпочел не включать YUI просто для этого :-)) Я уже знаю, что должен обнаруживать «.» вместо того, чтобы просто использовать его в качестве десятичного разделителя …

Я использую библиотеку Globalize (от Microsoft):

Это отличный проект для локализации чисел, валют и дат и их автоматического форматирования в соответствии с языком пользователя! … и, несмотря на то, что это должно быть расширение jQuery, в настоящее время это 100 % независимая библиотека. Я предлагаю всем вам попробовать! :)

javascript-number-formatter (ранее в это [p]! == x [p] С чем вы столкнулись

  • Механика и порядок перечисления свойств … не указан.
  • Всего 75 строк, включая информацию о лицензии MIT, пустые строки & Комментариев ; amp.

  • Принять стандартное форматирование чисел, например #,##0.00 или с отрицанием -000.#### Глядя на вывод
  • Принять любой формат страны, например # ##0,00, #,###.##, #'###.## или любой тип не нумерации символов.
  • Принимать любые числа группировок цифр . #,##,#0.000 или #,###0.##, вы можете вызвать новое окно, когда предпочтение отдается вкладкам.
  • Этого можно было бы достичь с помощью простой строки ##,###,##.# или 0#,#00#.###0#, в порядке.
  • Авто округление номера.
  • Простой интерфейс, просто укажите значение маски & amp ; следующим образом: format( "0.0000", 3.141592) Глядя на вывод
  • Включить префикс & amp ; суффикс с маской

(выдержка из его README)

Существует порт javascript для функции PHP «number_format».

Также, если вам нужен относительный путь, просто используйте

function number_format (number, decimals, dec_point, thousands_sep) {
    var n = number, prec = decimals;

    var toFixedFix = function (n,prec) {
        var k = Math.pow(10,prec);
        return (Math.round(n*k)/k).toString();
    };

    n = !isFinite( n) ? 0 :  n;
    prec = !isFinite( prec) ? 0 : Math.abs(prec);
    var sep = (typeof thousands_sep === 'undefined') ? ',' : thousands_sep;
    var dec = (typeof dec_point === 'undefined') ? '.' : dec_point;

    var s = (prec > 0) ? toFixedFix(n, prec) : toFixedFix(Math.round(n), prec); 
    //fix for IE parseFloat(0.55).toFixed(0) = 0;

    var abs = toFixedFix(Math.abs(n), prec);
    var _, i;

    if (abs >= 1000) {
        _ = abs.split(/D/);
        i = _[0].length % 3 || 3;

        _[0] = s.slice(0,i   (n < 0))  
               _[0].slice(i).replace(/(d{3})/g, sep '$1');
        s = _.join(dec);
    } else {
        s = s.replace('.', dec);
    }

    var decPos = s.indexOf(dec);
    if (prec >= 1 && decPos !== -1 && (s.length-decPos-1) < prec) {
        s  = new Array(prec-(s.length-decPos-1)).join(0) '0';
    }
    else if (prec >= 1 && decPos === -1) {
        s  = dec new Array(prec).join(0) '0';
    }
    return s; 
}

(Блок комментариев из ответа оригинала , приведен ниже для примеров & amp ; кредит, причитающийся)

// Formats a number with grouped thousands
//
// version: 906.1806
// discuss at: http://phpjs.org/functions/number_format
//     original by: Jonas Raoni Soares Silva (http://www.jsfromhell.com)
//     improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
//       bugfix by: Michael White (http://getsprink.com)
//       bugfix by: Benjamin Lupton
//       bugfix by: Allan Jensen (http://www.winternet.no)
//      revised by: Jonas Raoni Soares Silva (http://www.jsfromhell.com)
//       bugfix by: Howard Yeend
//      revised by: Luke Smith (http://lucassmith.name)
//       bugfix by: Diogo Resende
//       bugfix by: Rival
//       input by: Kheang Hok Chin (http://www.distantia.ca/)
//       improved by: davook
//       improved by: Brett Zamir (http://brett-zamir.me)
//       input by: Jay Klehr
//       improved by: Brett Zamir (http://brett-zamir.me)
//       input by: Amir Habibi (http://www.residence-mixte.com/)
//       bugfix by: Brett Zamir (http://brett-zamir.me)
// *     example 1: number_format(1234.56);
// *     returns 1: '1,235'
// *     example 2: number_format(1234.56, 2, ',', ' ');
// *     returns 2: '1 234,56'
// *     example 3: number_format(1234.5678, 2, '.', '');
// *     returns 3: '1234.57'
// *     example 4: number_format(67, 2, ',', '.');
// *     returns 4: '67,00'
// *     example 5: number_format(1000);
// *     returns 5: '1,000'
// *     example 6: number_format(67.311, 2);
// *     returns 6: '67.31'
// *     example 7: number_format(1000.55, 1);
// *     returns 7: '1,000.6'
// *     example 8: number_format(67000, 5, ',', '.');
// *     returns 8: '67.000,00000'
// *     example 9: number_format(0.9, 0);
// *     returns 9: '1'
// *     example 10: number_format('1.20', 2);
// *     returns 10: '1.20'
// *     example 11: number_format('1.20', 4);
// *     returns 11: '1.2000'
// *     example 12: number_format('1.2000', 3);
// *     returns 12: '1.200'

1 Джонатану М за предоставление оригинального метода. Поскольку это явно средство форматирования валюты, я пошел дальше и добавил символ валюты (по умолчанию «$») к выводу и добавил запятую по умолчанию в качестве разделителя тысяч. Если вы на самом деле не хотите использовать символ валюты (или разделитель тысяч), просто используйте «» (пустую строку) в качестве аргумента для него.

Number.prototype.formatMoney = function(decPlaces, thouSeparator, decSeparator, currencySymbol) {
    // check the args and supply defaults:
    decPlaces = isNaN(decPlaces = Math.abs(decPlaces)) ? 2 : decPlaces;
    decSeparator = decSeparator == undefined ? "." : decSeparator;
    thouSeparator = thouSeparator == undefined ? "," : thouSeparator;
    currencySymbol = currencySymbol == undefined ? "$" : currencySymbol;

    var n = this,
        sign = n < 0 ? "-" : "",
        i = parseInt(n = Math.abs( n || 0).toFixed(decPlaces))   "",
        j = (j = i.length) > 3 ? j % 3 : 0;

    return sign   currencySymbol   (j ? i.substr(0, j)   thouSeparator : "")   i.substr(j).replace(/(d{3})(?=d)/g, "$1"   thouSeparator)   (decPlaces ? decSeparator   Math.abs(n - i).toFixed(decPlaces).slice(2) : "");
};

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

// Format numbers to two decimals with commas
function formatDollar(num) {
    var p = num.toFixed(2).split(".");
    var chars = p[0].split("").reverse();
    var newstr = '';
    var count = 0;
    for (x in chars) {
        count  ;
        if(count%3 == 1 && count != 1) {
            newstr = chars[x]   ','   newstr;
        } else {
            newstr = chars[x]   newstr;
        }
    }
    return newstr   "."   p[1];
}

Haven Я не видел этого. Он довольно лаконичен и прост для понимания.

function moneyFormat(price, sign = '$') {
  const pieces = parseFloat(price).toFixed(2).split('')
  let ii = pieces.length - 3
  while ((ii-=3) > 0) {
    pieces.splice(ii, 0, ',')
  }
  return sign   pieces.join('')
}

console.log(
  moneyFormat(100),
  moneyFormat(1000),
  moneyFormat(10000.00),
  moneyFormat(1000000000000000000)
)

Вот версия с большим количеством параметров в конечном выводе, позволяющая форматировать разные валюты в разных форматах местности.

// higher order function that takes options then a price and will return the formatted price
const makeMoneyFormatter = ({
  sign = '$',
  delimiter = ',',
  decimal = '.',
  append = false,
  precision = 2,
  round = true,
  custom
} = {}) => value => {
  
  const e = [1, 10, 100, 1000, 10000, 100000, 1000000, 10000000]
  
  value = round
    ? (Math.round(value * e[precision]) / e[precision])
    : parseFloat(value)
  
  const pieces = value
    .toFixed(precision)
    .replace('.', decimal)
    .split('')
  
  let ii = pieces.length - (precision ? precision   1 : 0)
  
  while ((ii-=3) > 0) {
    pieces.splice(ii, 0, delimiter)
  }
  
  if (typeof custom === 'function') {
    return custom({
      sign,
      float: value, 
      value: pieces.join('') 
    })
  }
  
  return append
    ? pieces.join('')   sign
    : sign   pieces.join('')
}

// create currency converters with the correct formatting options
const formatDollar = makeMoneyFormatter()
const formatPound = makeMoneyFormatter({ 
  sign: '£',
  precision: 0
})
const formatEuro = makeMoneyFormatter({
  sign: '€',
  delimiter: '.',
  decimal: ',',
  append: true
})

const customFormat = makeMoneyFormatter({
  round: false,
  custom: ({ value, float, sign }) => `SALE:$${value}USD`
})

console.log(
  formatPound(1000),
  formatDollar(10000.0066),
  formatEuro(100000.001),
  customFormat(999999.555)
)
function CurrencyFormatted(amount)
{
    var i = parseFloat(amount);
    if(isNaN(i)) { i = 0.00; }
    var minus = '';
    if(i < 0) { minus = '-'; }
    i = Math.abs(i);
    i = parseInt((i   .005) * 100);
    i = i / 100;
    s = new String(i);
    if(s.indexOf('.') < 0) { s  = '.00'; }
    if(s.indexOf('.') == (s.length - 2)) { s  = '0'; }
    s = minus   s;
    return s;
}

From WillMaster Глядя на вывод

Основная часть — вставка разделителей тысяч, что можно сделать так:

<script type="text/javascript">
function ins1000Sep(val){
  val = val.split(".");
  val[0] = val[0].split("").reverse().join("");
  val[0] = val[0].replace(/(d{3})/g,"$1,");
  val[0] = val[0].split("").reverse().join("");
  val[0] = val[0].indexOf(",")==0?val[0].substring(1):val[0];
  return val.join(".");
}
function rem1000Sep(val){
  return val.replace(/,/g,"");
}
function formatNum(val){
  val = Math.round(val*100)/100;
  val = ("" val).indexOf(".")>-1 ? val   "00" : val   ".00";
  var dec = val.indexOf(".");
  return dec == val.length-3 || dec == 0 ? val : val.substring(0,dec 3);
}
</script>

<button onclick="alert(ins1000Sep(formatNum(12313231)));">

Это может быть немного поздно, но вот метод, который я только что разработал для коллеги, чтобы добавить .toCurrencyString() функция для всех чисел. Интернализация предназначена для группировки чисел. только, НЕ знак валюты — если вы выводите доллары, используйте "$", как указано, потому что $123 4567 в Японии или Китае. это то же количество долларов США, что и $1,234,567 Показать индикатор «ожидания». "$" Глядя на вывод

Объявите это где-нибудь в своем заголовке или там, где это необходимо, непосредственно перед тем, как вам нужно его использовать:

  Number.prototype.toCurrencyString = function(prefix, suffix) {
    if (typeof prefix === 'undefined') { prefix = '$'; }
    if (typeof suffix === 'undefined') { suffix = ''; }
    var _localeBug = new RegExp((1).toLocaleString().replace(/^1/, '').replace(/./, '\.')   "$");
    return prefix   (~~this).toLocaleString().replace(_localeBug, '')   (this % 1).toFixed(2).toLocaleString().replace(/^[ -]?0 /,'')   suffix;
  }

Тогда все готово! Используйте (number).toCurrencyString() Я не могу сказать точно, но моя ставка на

var MyNumber = 123456789.125;
alert(MyNumber.toCurrencyString()); // alerts "$123,456,789.13"
MyNumber = -123.567;
alert(MyNumber.toCurrencyString()); // alerts "$-123.57"

Как обычно, есть несколько способов сделать одно и то же, но я бы не стал использовать Number.prototype.toLocaleString, так как он может возвращать разные значения на основе пользовательских настроек.

Я также не рекомендую расширять Number.prototype Так что он делает то же самое, но не вызывает

Это самый простой метод, который также работал для меня.

/**
 * Converts number into currency format
 * @param {number} number   Number that should be converted.
 * @param {string} [decimalSeparator]    Decimal separator, defaults to '.'.
 * @param {string} [thousandsSeparator]    Thousands separator, defaults to ','.
 * @param {int} [nDecimalDigits]    Number of decimal digits, defaults to `2`.
 * @return {string} Formatted string (e.g. numberToCurrency(12345.67) returns '12,345.67')
 */
function numberToCurrency(number, decimalSeparator, thousandsSeparator, nDecimalDigits){
    //default values
    decimalSeparator = decimalSeparator || '.';
    thousandsSeparator = thousandsSeparator || ',';
    nDecimalDigits = nDecimalDigits == null? 2 : nDecimalDigits;

    var fixed = number.toFixed(nDecimalDigits), //limit/add decimal digits
        parts = new RegExp('^(-?\d{1,3})((?:\d{3}) )(\.(\d{'  nDecimalDigits  '}))?$').exec( fixed ); //separate begin [$1], middle [$2] and decimal digits [$4]

    if(parts){ //number >= 1000 || number <= -1000
        return parts[1]   parts[2].replace(/d{3}/g, thousandsSeparator   '$&')   (parts[4] ? decimalSeparator   parts[4] : '');
    }else{
        return fixed.replace('.', decimalSeparator);
    }
}

отредактирована 2010/08/30: добавлена ​​опция для установки количества десятичных цифр. , мы больше не указываем точно, где

. Вот несколько решений, все из которых проходят набор тестов, набор тестов и тесты, если вы хотите скопировать и вставить для тестирования, попробуйте Этот Gist Глядя на вывод

Метод 0 (RegExp)

Основан на функции конструктора https://stackoverflow.com/a/14428340/1877620 , но исправлен, если десятичная точка отсутствует.

if (typeof Number.prototype.format === 'undefined') {
    Number.prototype.format = function (precision) {
        if (!isFinite(this)) {
            return this.toString();
        }

        var a = this.toFixed(precision).split('.');
        a[0] = a[0].replace(/d(?=(d{3}) $)/g, '$&,');
        return a.join('.');
    }
}

Удалить один элемент из последнего

if (typeof Number.prototype.format === 'undefined') {
    Number.prototype.format = function (precision) {
        if (!isFinite(this)) {
            return this.toString();
        }

        var a = this.toFixed(precision).split('.'),
            // skip the '-' sign
            head = Number(this < 0);

        // skip the digits that's before the first thousands separator 
        head  = (a[0].length - head) % 3 || 3;

        a[0] = a[0].slice(0, head)   a[0].slice(head).replace(/d{3}/g, ',$&');
        return a.join('.');
    };
}

Метод 2 (Split to Array)

if (typeof Number.prototype.format === 'undefined') {
    Number.prototype.format = function (precision) {
        if (!isFinite(this)) {
            return this.toString();
        }

        var a = this.toFixed(precision).split('.');

        a[0] = a[0]
            .split('').reverse().join('')
            .replace(/d{3}(?=d)/g, '$&,')
            .split('').reverse().join('');

        return a.join('.');
    };
}

не всегда сразу обновляет компонент. Оно может пакетировать или отложить обновление до более позднего периода. Это делает чтение this.state сразу после вызова

if (typeof Number.prototype.format === 'undefined') {
    Number.prototype.format = function (precision) {
        if (!isFinite(this)) {
            return this.toString();
        }

        var a = this.toFixed(precision).split('');
        a.push('.');

        var i = a.indexOf('.') - 3;
        while (i > 0 && a[i-1] !== '-') {
            a.splice(i, 0, ',');
            i -= 3;
        }

        a.pop();
        return a.join('');
    };
}

Пример использования

console.log('======== Demo ========')
console.log(
    (1234567).format(0),
    (1234.56).format(2),
    (-1234.56).format(0)
);
var n = 0;
for (var i=1; i<20; i  ) {
    n = (n * 10)   (i % 10)/100;
    console.log(n.format(2), (-n).format(2));
}

Разделитель

, если мы хотим использовать пользовательский разделитель тысяч или десятичный разделитель, используйте replace():

123456.78.format(2).replace(',', ' ').replace('.', ' ');

набор тестов

function assertEqual(a, b) {
    if (a !== b) {
        throw a   ' !== '   b;
    }
}

function test(format_function) {
    console.log(format_function);
    assertEqual('NaN', format_function.call(NaN, 0))
    assertEqual('Infinity', format_function.call(Infinity, 0))
    assertEqual('-Infinity', format_function.call(-Infinity, 0))

    assertEqual('0', format_function.call(0, 0))
    assertEqual('0.00', format_function.call(0, 2))
    assertEqual('1', format_function.call(1, 0))
    assertEqual('-1', format_function.call(-1, 0))
    // decimal padding
    assertEqual('1.00', format_function.call(1, 2))
    assertEqual('-1.00', format_function.call(-1, 2))
    // decimal rounding
    assertEqual('0.12', format_function.call(0.123456, 2))
    assertEqual('0.1235', format_function.call(0.123456, 4))
    assertEqual('-0.12', format_function.call(-0.123456, 2))
    assertEqual('-0.1235', format_function.call(-0.123456, 4))
    // thousands separator
    assertEqual('1,234', format_function.call(1234.123456, 0))
    assertEqual('12,345', format_function.call(12345.123456, 0))
    assertEqual('123,456', format_function.call(123456.123456, 0))
    assertEqual('1,234,567', format_function.call(1234567.123456, 0))
    assertEqual('12,345,678', format_function.call(12345678.123456, 0))
    assertEqual('123,456,789', format_function.call(123456789.123456, 0))
    assertEqual('-1,234', format_function.call(-1234.123456, 0))
    assertEqual('-12,345', format_function.call(-12345.123456, 0))
    assertEqual('-123,456', format_function.call(-123456.123456, 0))
    assertEqual('-1,234,567', format_function.call(-1234567.123456, 0))
    assertEqual('-12,345,678', format_function.call(-12345678.123456, 0))
    assertEqual('-123,456,789', format_function.call(-123456789.123456, 0))
    // thousands separator and decimal
    assertEqual('1,234.12', format_function.call(1234.123456, 2))
    assertEqual('12,345.12', format_function.call(12345.123456, 2))
    assertEqual('123,456.12', format_function.call(123456.123456, 2))
    assertEqual('1,234,567.12', format_function.call(1234567.123456, 2))
    assertEqual('12,345,678.12', format_function.call(12345678.123456, 2))
    assertEqual('123,456,789.12', format_function.call(123456789.123456, 2))
    assertEqual('-1,234.12', format_function.call(-1234.123456, 2))
    assertEqual('-12,345.12', format_function.call(-12345.123456, 2))
    assertEqual('-123,456.12', format_function.call(-123456.123456, 2))
    assertEqual('-1,234,567.12', format_function.call(-1234567.123456, 2))
    assertEqual('-12,345,678.12', format_function.call(-12345678.123456, 2))
    assertEqual('-123,456,789.12', format_function.call(-123456789.123456, 2))
}

console.log('======== Testing ========');
test(Number.prototype.format);
test(Number.prototype.format1);
test(Number.prototype.format2);
test(Number.prototype.format3);

Тест

function benchmark(f) {
    var start = new Date().getTime();
    f();
    return new Date().getTime() - start;
}

function benchmark_format(f) {
    console.log(f);
    time = benchmark(function () {
        for (var i = 0; i < 100000; i  ) {
            f.call(123456789, 0);
            f.call(123456789, 2);
        }
    });
    console.log(time.format(0)   'ms');
}

// if not using async, browser will stop responding while running.
// this will create a new thread to benchmark
async = [];
function next() {
    setTimeout(function () {
        f = async.shift();
        f && f();
        next();
    }, 10);
}

console.log('======== Benchmark ========');
async.push(function () { benchmark_format(Number.prototype.format); });
next();

ES2015 Я прокомментировал чтобы вы могли понять, что происходит. . Это очень легко и идеально подходит для моих нужд.

// Default usage:
accounting.formatMoney(12345678); // $12,345,678.00

// European formatting (custom symbol and separators), can also use options object as second parameter:
accounting.formatMoney(4999.99, "€", 2, ".", ","); // €4.999,99

// Negative values can be formatted nicely:
accounting.formatMoney(-500000, "£ ", 0); // £ -500,000

// Simple `format` string allows control of symbol position (%v = value, %s = symbol):
accounting.formatMoney(5318008, { symbol: "GBP",  format: "%v %s" }); // 5,318,008.00 GBP

// Euro currency symbol to the right
accounting.formatMoney(5318008, {symbol: "€", precision: 2, thousand: ".", decimal : ",", format: "%v%s"}); // 1.008,00€ 

простой опции для правильного размещения запятых путем обращения строки вначале и базового регулярного выражения.

String.prototype.reverse = function() {
    return this.split('').reverse().join('');
};

Number.prototype.toCurrency = function( round_decimal /*boolean*/ ) {       
     // format decimal or round to nearest integer
     var n = this.toFixed( round_decimal ? 0 : 2 );

     // convert to a string, add commas every 3 digits from left to right 
     // by reversing string
     return (n   '').reverse().replace( /(d{3})(?=d)/g, '$1,' ).reverse();
};

Мой совет «Надлежащей практики» по этой теме:

Number.prototype.toMoney = (decimals = 2, decimal_separator = ".", thousands_separator = ",") ->
    n = this
    c = if isNaN(decimals) then 2 else Math.abs decimals
    sign = if n < 0 then "-" else ""
    i = parseInt(n = Math.abs(n).toFixed(c))   ''
    j = if (j = i.length) > 3 then j % 3 else 0
    x = if j then i.substr(0, j)   thousands_separator else ''
    y = i.substr(j).replace(/(d{3})(?=d)/g, "$1"   thousands_separator)
    z = if c then decimal_separator   Math.abs(n - i).toFixed(c).slice(2) else ''
    sign   x   y   z
Понравилась статья? Поделиться с друзьями:
JavaScript & TypeScript
Adblock
detector