Wie formatiere ich Zahlen als Währungszeichenfolge?

1846

Ich möchte einen Preis in JavaScript formatieren. Ich möchte eine Funktion, die a floatals Argument verwendet und eine folgende stringFormatierung zurückgibt :

"$ 2,500.00"

Was ist der beste Weg, dies zu tun?

Daniel Magliola
quelle
8
Es gibt keine eingebaute Funktion formatNumberin Javascript
Zerkms
500
Bitte, zu jemandem dies in der Zukunft zu lesen, Sie nicht verwenden float zu speichern Währung. Sie verlieren Präzision und Daten. Sie sollten es als ganzzahlige Anzahl von Cent (oder Pennies usw.) speichern und dann vor der Ausgabe konvertieren.
Philip Whitehouse
8
@ user1308743 Float speichert keine Dezimalstellen. Es speichert Zahlen mit einem Wert, einer Basis und einem Versatz. 0,01 ist eigentlich nicht darstellbar. Siehe: en.wikipedia.org/wiki/Floating_point#Accuracy_problems
Philip Whitehouse
6
@ user1308743: Stellen Sie sich vor, Sie repräsentieren eine sehr große Zahl (sagen wir, Sie sind ein Glückspilz und es ist Ihr Kontostand). Möchten Sie wirklich wegen eines Präzisionsmangels Geld verlieren?
ereOn
163
Warum hat niemand Folgendes vorgeschlagen? (2500) .toLocaleString ("en-GB", {Stil: "Währung", Währung: "GBP", MinimumFractionDigits: 2}) developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Nick Grealy

Antworten:

1792

Number.prototype.toFixed

Diese Lösung ist mit jedem einzelnen großen Browser kompatibel:

  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)

Alles was Sie brauchen, ist das Währungssymbol (zB "$" + profits.toFixed(2)) hinzuzufügen und Sie haben Ihren Betrag in Dollar.

Benutzerdefinierte Funktion

Wenn Sie die Verwendung ,zwischen den einzelnen Ziffern benötigen , können Sie diese Funktion verwenden:

function formatMoney(number, decPlaces, decSep, thouSep) {
decPlaces = isNaN(decPlaces = Math.abs(decPlaces)) ? 2 : decPlaces,
decSep = typeof decSep === "undefined" ? "." : decSep;
thouSep = typeof thouSep === "undefined" ? "," : thouSep;
var sign = number < 0 ? "-" : "";
var i = String(parseInt(number = Math.abs(Number(number) || 0).toFixed(decPlaces)));
var j = (j = i.length) > 3 ? j % 3 : 0;

return sign +
	(j ? i.substr(0, j) + thouSep : "") +
	i.substr(j).replace(/(\decSep{3})(?=\decSep)/g, "$1" + thouSep) +
	(decPlaces ? decSep + Math.abs(number - i).toFixed(decPlaces).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>

Verwenden Sie es so:

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

Wenn Sie immer '.' und ',' können Sie sie aus Ihrem Methodenaufruf auslassen, und die Methode wird sie standardmäßig für Sie festlegen.

(123456789.12345).formatMoney(2);

Wenn in Ihrer Kultur die beiden Symbole umgedreht sind (z. B. Europäer) und Sie die Standardeinstellungen verwenden möchten, fügen Sie einfach die folgenden zwei Zeilen in die formatMoneyMethode ein:

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

Benutzerdefinierte Funktion (ES6)

Wenn Sie die moderne ECMAScript-Syntax (dh über Babel) verwenden können, können Sie stattdessen diese einfachere Funktion verwenden:

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>

Haykam
quelle
26
Zunächst einmal exzellenter, prägnanter Code. jedoch, wenn Sie Amerikaner sind, sollten Sie die Standardeinstellungen von ändern dund tzu sein .und ,jeweils so , dass Sie sie nicht haben jedes Mal zu spezifizieren. Außerdem empfehle ich, den Anfang der returnAnweisung so zu ändern return s + '$' + [rest], dass er lautet: Andernfalls erhalten Sie kein Dollarzeichen.
Jason
744
Ich bin mir nicht sicher, warum die Leute diesen Code für schön halten. Es ist nicht zu entziffern. Es scheint gut zu funktionieren, aber es ist nicht schön.
usr
86
Wird diese formatMoney-Funktion irgendwo aus einem minimierten JavaScript-Code kopiert? Kannst du das Original nicht posten? Wofür stehen die Variablen c, d, i, j, n, s und t? Gemessen an der Anzahl der Upvotes und Kommentare in diesem Beitrag kann ich davon ausgehen, dass dieser Code überall in Produktionswebsites eingefügt wurde ... Viel Glück beim Beibehalten des Codes, wenn er eines Tages einen Fehler aufweist!
zuallauz
259
"Poesie"? Eher wie Dunkelheit. Dies ist kein Code Golf; Verwenden Sie einen kleinen Leerraum. Richtige Var-Namen würden auch nicht schaden.
Keithjgrant
1513

Intl.numberformat

Javascript hat einen Zahlenformatierer (Teil der Internationalisierungs-API).

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

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

JS Geige

Verwenden Sie undefinedanstelle des ersten Arguments ( 'en-US'im Beispiel) das Systemgebietsschema (das Benutzergebietsschema, falls der Code in einem Browser ausgeführt wird). Weitere Erläuterung des Gebietsschemacodes .

Hier ist eine Liste der Währungscodes .

Intl.NumberFormat vs Number.prototype.toLocaleString

Ein letzter Hinweis zum Vergleich mit dem älteren. toLocaleString. Beide bieten im Wesentlichen die gleiche Funktionalität. ToLocaleString in seinen älteren Inkarnationen (vor Intl) unterstützt jedoch keine Gebietsschemas : Es verwendet das Systemgebietsschema. Stellen Sie daher sicher, dass Sie die richtige Version verwenden ( MDN empfiehlt, die Existenz von zu überprüfenIntl ). Außerdem ist die Leistung beider für ein einzelnes Element gleich. Wenn Sie jedoch viele Zahlen formatieren müssen, ist die Verwendung Intl.NumberFormat~ 70-mal schneller. So verwenden Sie toLocaleString:

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

Einige Hinweise zur Browserunterstützung

  • Die Browserunterstützung ist heutzutage kein Problem mehr. 97,5% unterstützen weltweit, 98% in den USA und 99% in der EU
  • Es gibt eine Unterlegscheibe , die dies in versteinerten Browsern (wie IE8) unterstützt, falls Sie dies wirklich benötigen
  • Weitere Informationen finden Sie in CanIUse
aross
quelle
89
Diese idomatische, einfache und elegante JavaScript-Lösung ist genau das, wonach ich gesucht habe.
Guilhem Soulas
9
Wählen Sie diese, weil es eine dumm einfache Antwort ist, die von Haus aus funktioniert.
Trasiva
17
Ziemlich sicher, dass ein ziemlich hoher Prozentsatz der Browser dies jetzt unterstützt. Dies sollte viel mehr positiv bewertet werden.
Flq
2
Dies ist eine großartige Antwort, und ich habe sie mit einem dynamischen Währungswert arbeiten lassen. Wenn sie also in Europa verwendet wird, ändert sie sich in EUR und zeigt das Euro-Zeichen. Funktioniert ein Genuss!
Sprose
3
Es ist 2018 und dies wird grundsätzlich überall unterstützt. Dies sollte die richtige Antwort sein.
Sarink
1340

Kurze und schnelle Lösung (funktioniert überall!)

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

Die Idee hinter dieser Lösung besteht darin, übereinstimmende Abschnitte durch erste Übereinstimmung und Komma zu ersetzen, d '$&,'. H. Der Abgleich erfolgt nach dem Lookahead-Ansatz . Sie können den Ausdruck als "Übereinstimmung mit einer Zahl, wenn darauf eine Folge von drei Zahlensätzen (einer oder mehrere) und einem Punkt folgt" lesen .

TESTS:

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/


Erweiterte Kurzlösung

Sie können den NumberObjektprototyp auch erweitern , um zusätzliche Unterstützung für eine beliebige Anzahl von Dezimalstellen [0 .. n]und die Größe von Zahlengruppen hinzuzufügen [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"

DEMO / TESTS: http://jsfiddle.net/hAfMM/435/


Super erweiterte kurze Lösung

In dieser super erweiterten Version können Sie verschiedene Trennzeichentypen festlegen:

/**
 * 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"

DEMO / TESTS: http://jsfiddle.net/hAfMM/612/

VisioN
quelle
21
Ich bin sogar noch einen Schritt weiter gegangen : .replace(/(\d)(?=(\d{3})+(?:\.\d+)?$)/g, "$1,").
Kalisjoshua
4
CoffeeScript-Version mit visioN & kalisjoshua regexp und Art der Angabe der Dezimalstelle (so können Sie die Standardeinstellung 2 Number.prototype.toMoney = (decimal=2) -> @toFixed(decimal).replace /(\d)(?=(\d{3})+(?:\.\d+)?$)/g, "$1,"
Eric Anderson
11
@Abbas Ja, ersetzt \.mit $(Ende der Zeile), dh this.toFixed(0).replace(/(\d)(?=(\d{3})+$)/g, "$1,").
VisioN
2
@hanumant Die reguläre Grammatik ist hier etwas kompliziert, daher empfehle ich Ihnen, zuerst die Handbücher über reguläre Ausdrücke zu lesen (z . B. bei MDN ). Die Idee dahinter ist, übereinstimmende Abschnitte durch erste Übereinstimmung und Komma zu ersetzen, dh $1,. Der Abgleich erfolgt nach dem Lookahead-Ansatz . Sie können den Ausdruck als "Übereinstimmung mit einer Zahl, wenn darauf eine Folge von drei Zahlensätzen (einer oder mehrere) und einem Punkt folgt" lesen .
VisioN
2
@ JuliendePrabère Bitte geben Sie ein Beispiel für eine lange Zahl, die mit diesem Ansatz nicht funktioniert.
VisioN
248

Schauen Sie sich das JavaScript Number- Objekt an und prüfen Sie, ob es Ihnen helfen kann.

  • toLocaleString() formatiert eine Zahl mit einem standortspezifischen Tausendertrennzeichen.
  • toFixed() rundet die Zahl auf eine bestimmte Anzahl von Dezimalstellen.

Um diese gleichzeitig zu verwenden, muss der Typ des Werts wieder in eine Zahl geändert werden, da beide eine Zeichenfolge ausgeben.

Beispiel:

Number((someNumber).toFixed(1)).toLocaleString()
17 von 26
quelle
2
Vielen Dank! Basierend auf dieser Idee konnte ich eine erstellen, die kurz und einfach genug ist! (und lokalisiert) Ausgezeichnet.
Daniel Magliola
7
Eigentlich kannst du. dh für Dollar: '$' + (Wert + 0,001) .toLocaleString (). Slice (0, -1)
Zaptree
6
Sieht so aus, als wäre es großartig, aber im Moment gibt es wenig Browser-Unterstützung
acorncom
1
@acorncom Warum gibt es Ihrer Meinung nach "wenig Browser-Unterstützung"? Das Number-Objekt gibt es seit Javascript 1.1. Bitte geben Sie eine Referenz an, die Ihren Anspruch bestätigt.
Doug S
2
Es sollte darauf geachtet werden, dass es eine alte Version gibt toLocaleString, die das Systemgebietsschema verwendet, und eine neue (inkompatible) Version , die von der ECMAScript Intl API stammt. Hier erklärt . Diese Antwort scheint für die alte Version gedacht zu sein.
Über
162

Unten finden Sie den Code von Patrick Desjardins (alias Daok) mit einigen Kommentaren und einigen geringfügigen Änderungen:

/* 
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 [/programming/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) : ''); 
}

und hier einige Tests:

//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));

Die geringfügigen Änderungen sind:

  1. etwas bewegt das Math.abs(decimals)nur zu tun ist wenn nicht NaN.

  2. decimal_sep kann keine leere Zeichenfolge mehr sein (eine Art Dezimaltrennzeichen ist ein MUSS)

  3. Wir verwenden typeof thousands_sep === 'undefined'wie in Wie am besten vorgeschlagen, um festzustellen, ob ein Argument nicht an die JavaScript-Funktion gesendet wird

  4. (+n || 0)wird nicht benötigt, da thises sich um ein NumberObjekt handelt

JS Fiddle

Marco Demaio
quelle
8
Möglicherweise möchten Sie '10' als Radix in parseInt verwenden. Andernfalls verwendet jede Zahl, die mit '0' beginnt, eine oktale Nummerierung.
Sohtimsso1970
3
@ sohtimsso1970: Entschuldigung für die späte Antwort, aber könnten Sie noch etwas erklären? Ich sehe nicht, wo eine Zahl als oktal interpretiert werden könnte. Das parseIntwird auf den absoluten Wert des INTEGER-Teils der Zahl aufgerufen. Der INTEGER-Teil kann nicht mit NULL beginnen, es sei denn, es ist nur NULL! Und parseInt(0) === 0entweder oktal oder dezimal.
Marco Demaio
Versuchen Sie zum Beispiel: parseInt ("016") ... gibt 14 zurück, da parseInt davon ausgeht, dass es oktal codiert ist, wenn die Zeichenfolge mit einer Null beginnt.
Tracker1
4
@ Tracker1: Ich habe verstanden, dass eine Zahl, die mit beginnt, von 0als oktal betrachtet wird parseInt. In diesem Code ist es jedoch UNMÖGLICH parseInt, 016als Eingabe (oder einen anderen oktalformatierten Wert) zu empfangen , da das übergebene Argument zuerst parseIntvon der Math.absFunktion verarbeitet wird . Es gibt also keine Möglichkeit parseInt, eine Zahl zu erhalten, die mit Null beginnt, es sei denn, es ist nur eine Null oder 0.nn(wo nnsind Dezimalstellen). Aber beide 0und 0.nnZeichenfolgen würden wie angenommen parseIntin eine einfache NULL umgewandelt.
Marco Demaio
Diese Funktion ist falsch:> (2030) .toMoney (0, '.', ''); <"2 03 0"
Anton P Robul
124

Accounting.js ist eine winzige JavaScript-Bibliothek für die Formatierung von Zahlen, Geld und Währungen.

GasheK
quelle
... denken Sie daran, ein Währungssymbol zu übergeben, da es sonst in IE7 und IE8 fehlerhaft ist. IE9 ist in beiden Fällen in Ordnung
Vektor
2
Der IE7 / IE8-Fehler scheint behoben zu sein.
Mat Schaffer
2
Dies ist eine großartige Bibliothek. Es ist auch eine gute Idee, das Währungssymbol übergeben zu können, da alle Währungsdetails in den einzelnen Funktionsaufrufen / Einstellungen enthalten sind
farinspace
2
Ich mag die Tatsache, dass Sie das Gegenteil tun können - übergeben Sie eine formatierte Währungszeichenfolge und erhalten Sie den numerischen Wert.
Neil Monroe
2
Buchhaltung.js scheint in letzter Zeit nicht gepflegt zu sein. Eine Gabelung mit den letzten Änderungen ist github.com/nashdot/accounting-js
RationalDev mag GoFundMonica
124

Wenn der Betrag beispielsweise eine Zahl ist -123, dann

amount.toLocaleString('en-US', { style: 'currency', currency: 'USD' });

wird die Zeichenfolge erzeugen "-$123.00".

Hier ist ein komplettes Arbeits Beispiel .

cs01
quelle
7
Diese Antwort war fast für mich da, aber ich musste sie auf den nächsten Cent runden. Dies ist, was ich Betrag verwendet habe.toLocaleString ('en-GB', {Stil: 'Währung', Währung: 'GBP', MaximumFractionDigits: 2});
Nico
Der obige Code rundet auf die gewünschte Anzahl von Stellen. Sehen Sie sich das Beispiel an und geben Sie 1.237 in das Eingabefeld ein.
Daniel Barbalace
3
Scheint in Safari nicht zu funktionieren. Es gibt nur die Nummer als String ohne Formatierung zurück.
Lance Anderson
1
Wow, das ist eine wirklich gute Antwort. Sollte oben sein.
Ethan
2
Wenn Sie aus irgendeinem Grund keine Cent möchten, können Sie die Dezimalgenauigkeit ändern mit:minimumFractionDigits: 0
Horacio
99

Hier ist der beste Geldformatierer, den ich je gesehen habe:

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) : "");
};

Es wurde neu formatiert und von hier ausgeliehen: https://stackoverflow.com/a/149099/751484

Sie müssen Ihren eigenen Währungsbezeichner angeben (Sie haben $ oben verwendet).

Nennen Sie es so (beachten Sie jedoch, dass die Argumente standardmäßig 2, Komma und Punkt sind, sodass Sie keine Argumente angeben müssen, wenn Sie dies bevorzugen):

var myMoney=3543.75873;
var formattedMoney = '$' + myMoney.formatMoney(2,',','.'); // "$3,543.76"
Jonathan M.
quelle
Achten Sie auf globale Zeichen, ich, j
Hacklikecrack
6
@hacklikecrack, alle Variablen sind lokal; Sie sind in der varAussage.
Jonathan M
3
Entschuldigung, ja, obwohl Sie die Argumente neu deklarieren. Vertiefung! ;)
Hacklikecrack
Schreckliche Verwendung von Variablennamen!
Serj Sagan
77

Hier gibt es bereits einige gute Antworten. Hier ist ein weiterer Versuch, nur zum Spaß:

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];
}

Und einige Tests:

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

Bearbeitet: Jetzt werden auch negative Zahlen verarbeitet

Wayne Burkett
quelle
Poesie. brillant. Haben Sie versucht, reduRight () developer.mozilla.org/en/JavaScript/Reference/Global_Objects/… zu reduzieren, wodurch das reverse () beseitigt werden sollte?
Steve
1
@Steve - Sie haben Recht, aber Sie müssten etwas wie i = orig.length - i - 1im Rückruf tun . Trotzdem eine Durchquerung des Arrays weniger.
Wayne
11
Nicht zur Kompatibilität: Die reduceMethode wurde in Ecmascript 1.8 eingeführt und wird in Internet Explorer 8 und niedriger nicht unterstützt.
Blaise
Wie @Blaise sagte, funktioniert diese Methode in IE 8 oder niedriger nicht.
Rsbarro
Ja, das ist natürlich richtig. Wie in der Antwort selbst erwähnt, ist dies nur zum Spaß. Außerdem sollte es gut mit negativen Zahlen umgehen können.
Wayne
76

Funktioniert für alle aktuellen Browser

Verwenden Sie toLocaleStringeine andere Währung zu formatieren in seinem sprachsensitiven Darstellung (mit ISO 4217 - Währungscodes).

(2500).toLocaleString("en-GB", {style: "currency", currency: "GBP", minimumFractionDigits: 2}) 

Beispiel südafrikanischer Rand-Code-Schnipsel für @avenmore

console.log((2500).toLocaleString("en-ZA", {style: "currency", currency: "ZAR", minimumFractionDigits: 2}))
// -> R 2 500,00
console.log((2500).toLocaleString("en-GB", {style: "currency", currency: "ZAR", minimumFractionDigits: 2}))
// -> ZAR 2,500.00

Nick Grealy
quelle
1
Da die Argumente "Gebietsschemas" und "Optionen" nur von einer sehr kleinen Anzahl von Browsern wie Chrome 24, IE11 und Opera 15 unterstützt werden, werden sie von Firefox, Safari und älteren Versionen anderer noch immer nicht unterstützt.
VisioN
3
Einverstanden, es wird (noch) nicht in allen Browsern vollständig unterstützt, aber es ist immer noch eine Lösung. (Und wohl die gültigste Lösung, da sie vorwärts mit den nicht unterstützten Browsern kompatibel ist und eine dokumentierte Funktion der Javascript-API ist.)
Nick Grealy
1
Ich mag das und bin froh, dass es mit der indischen Zifferngruppierung funktioniert.
MSC
7
Dies wird ab 2017 voll unterstützt und sollte die einzig richtige Antwort sein
Evgeny
1
Neueste und größte :) FF69, Chrome76 usw. "R 2 500,00" wird hier nicht verwendet, es sollte "R 2.500,00" sein, genau wie bei en-GB.
Avenmore
70

Ich denke was du willst ist f.nettotal.value = "$" + showValue.toFixed(2);

zerquetschen
quelle
@ Crush das funktioniert aber es trägt die Berechnungen nicht mehr auf das Steuerfeld?
Rocco The Taco
11
Sobald Sie ein $ -Zeichen daran anhängen, ist es keine Zahl mehr, sondern eine Zeichenfolge.
Crush
Diese Option setzt kein Komma zwischen den Tausenden. :-(
Simon East
29

Numeral.js - eine js-Bibliothek zur einfachen Formatierung von Zahlen durch @adamwdraper

numeral(23456.789).format('$0,0.00'); // = "$23,456.79"
Yarin
quelle
Die Gabel Numbro scheint mehr Liebe zu bekommen, da Numeral.js verlassen zu sein scheint: github.com/foretagsplatsen/numbro
RationalDev mag GoFundMonica
Numeral.js ist wieder aktiv.
Adamwdraper
27

Ok, basierend auf dem, was du gesagt hast, benutze ich Folgendes:

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;

Ich bin offen für Verbesserungsvorschläge (ich würde es vorziehen, YUI nicht einzuschließen, nur um dies zu tun :-)) Ich weiß bereits, dass ich das "erkennen" sollte. anstatt es nur als Dezimaltrennzeichen zu verwenden ...

Daniel Magliola
quelle
8
Beachten Sie, dass Ihre Version nicht richtig auf zwei Dezimalstellen gerundet wird. Zum Beispiel würde 3.706 als "£ 3.70" formatiert, nicht als "£ 3.71", wie es sein soll.
Ates Goral
Ja, das ist in meinem speziellen Fall in Ordnung, da die Beträge, mit denen ich arbeite, bereits höchstens 2 Stellen haben. Der Grund, warum ich mich auf 2 Dezimalstellen festlegen muss, ist für Beträge ohne Dezimalstellen oder mit nur 1.
Daniel Magliola
26

Ich benutze die Bibliothek Globalize (von Microsoft):

Es ist ein großartiges Projekt, Zahlen, Währungen und Daten zu lokalisieren und sie automatisch entsprechend dem Gebietsschema des Benutzers richtig formatieren zu lassen! ... und obwohl es sich um eine jQuery-Erweiterung handeln sollte, handelt es sich derzeit um eine 100% unabhängige Bibliothek. Ich schlage Ihnen allen vor, es auszuprobieren! :) :)

Daveoncode
quelle
3
Wow, warum wird das nicht mehr positiv bewertet? Große standardisierte Bibliothek für alle Arten von Formatierungen. Formatierungsparameter nach Industriestandard mit korrekter Globalisierung. Gute Antwort!!
Pbarranis
Es wird immer noch als Alpha-Stadium betrachtet, also vorsichtig verwenden, aber großartig finden.
Neil Monroe
1
Nicht mehr in Alpha (oder Beta). Dies scheint sehr nützlich zu sein, während wir darauf warten, dass Safari den neuen Standard erfüllt und IE <11 stirbt.
Guy Schalnat
25

Javascript-Nummer-Formatierer (früher bei Google Code )

  • Kurz, schnell, flexibel und dennoch eigenständig. Nur 75 Zeilen einschließlich MIT-Lizenzinformationen, Leerzeilen und Kommentaren.
  • Akzeptieren Sie die Standardformatierung von Zahlen wie #,##0.00oder mit Negation -000.####.
  • Akzeptieren jedes Land Format wie # ##0,00, #,###.##, #'###.##oder jede Art von nicht-Nummerierung Symbol.
  • Akzeptieren Sie eine beliebige Anzahl von Zifferngruppierungen. #,##,#0.000oder #,###0.##sind alle gültig.
  • Akzeptieren Sie redundante / narrensichere Formatierungen. ##,###,##.#oder 0#,#00#.###0#sind alle in Ordnung.
  • Automatische Nummernrundung.
  • Einfache Oberfläche, geben Sie einfach Maske & Wert wie folgt ein : format( "0.0000", 3.141592).
  • Fügen Sie der Maske ein Präfix und ein Suffix hinzu

(Auszug aus der README-Datei)

Goodeq
quelle
23

+1 an Jonathan M für die Bereitstellung der ursprünglichen Methode. Da dies explizit ein Währungsformatierer ist, habe ich das Währungssymbol (standardmäßig '$') zur Ausgabe hinzugefügt und ein Standardkomma als Tausendertrennzeichen hinzugefügt. Wenn Sie eigentlich kein Währungssymbol (oder Tausendertrennzeichen) möchten, verwenden Sie einfach "" (leere Zeichenfolge) als Argument dafür.

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) : "");
};
XML
quelle
Die erste Variable ist etwas seltsam, da diese Variablen bereits in der Funktionsdeklaration deklariert sind. Ansonsten danke!
Rich Bradshaw
2
Du hast recht. Das ist ein Fehler, den ich aus Jonathan Ms Original mitgebracht habe, wo sie alle als ein einziger var-Ausdruck verkettet sind. Das sollten einfache Aufgaben sein. Festsetzung.
XML
Im Übrigen denke ich, dass dies wahrscheinlich vorzeitig optimiert ist und aus Gründen der Lesbarkeit überarbeitet werden sollte. Mein Ziel war es jedoch, den OP-Code zu erweitern und nicht grundlegend zu ändern.
XML
Es ist nicht schlecht - das +n || 0ist das einzige, was ein bisschen seltsam erscheint (für mich jedenfalls).
Rich Bradshaw
2
thisist ein sehr nützlicher Variablenname. Die Konvertierung in, ndamit Sie zur Definitionszeit 3 ​​Zeichen speichern können, war möglicherweise in einer Zeit erforderlich, in der RAM und Bandbreite in KB gezählt wurden, ist jedoch in einer Zeit, in der sich der Minifier um alles kümmert, bevor er jemals die Produktion erreicht, nur verschleiert. Die anderen cleveren Mikrooptimierungen sind zumindest umstritten.
XML
22

Es gibt einen Javascript-Port der PHP-Funktion "number_format".

Ich finde es sehr nützlich, da es für PHP-Entwickler einfach zu bedienen und erkennbar ist.

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

(Kommentarblock vom Original , unten für Beispiele und Gutschrift, wo fällig)

// 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'
DaMayan
quelle
Dies ist nur eine korrekte Funktion:> number_format (2030, 0, '.', '') <'2 030' Großartig! Vielen Dank
Anton P Robul
21

Eine kürzere Methode (zum Einfügen von Leerzeichen, Komma oder Punkt) mit regulärem Ausdruck?

    Number.prototype.toCurrencyString=function(){
        return this.toFixed(2).replace(/(\d)(?=(\d{3})+\b)/g,'$1 ');
    }

    n=12345678.9;
    alert(n.toCurrencyString());
Julien de Prabère
quelle
20

Ich habe so etwas noch nicht gesehen. Es ist ziemlich prägnant und leicht zu verstehen.

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)
)

Hier ist eine Version mit mehr Optionen in der endgültigen Ausgabe, um die Formatierung verschiedener Währungen in verschiedenen Lokalitätsformaten zu ermöglichen.

// 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)
)

synthet1c
quelle
Tolles Code-Snippet, danke. Seien Sie jedoch vorsichtig, da dies im IE nicht funktioniert, da Standardparameter nicht unterstützt werden und "const" und "let" in <IE11 nicht unterstützt werden. Ue dies zu beheben: + moneyFormat: Funktion (Preis, Zeichen) {+ if (! Zeichen) sign = '$'; + Stück = parseFloat (Preis) .toFixed (2) .split ('') + var ii = Stück.Länge - 3
Charlie Dalsass
Keine Sorge @CharlieDalsass. Ich würde empfehlen, babel zu verwenden, um es für Produktionscode auf ES5 zu kompilieren.
synthet1c
Aber wie macht man Euro-Währung? 1.000,00 Euro?
@YumYumYum Ich habe ein vollständiges Beispiel mit mehr Formatierungsoptionen hinzugefügt, um mehr Flexibilität zu ermöglichen.
synthet1c
18

Die Antwort von Patrick Desjardins sieht gut aus, aber ich bevorzuge mein einfaches Javascript. Hier ist eine Funktion, die ich gerade geschrieben habe, um eine Zahl aufzunehmen und im Währungsformat zurückzugeben (abzüglich des Dollarzeichens).

// 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];
}
Tim Saylor
quelle
Ich brauchte etwas, um sowohl im Browser als auch in einer alten Version von Node zu funktionieren. Das hat perfekt funktioniert. Danke
n8jadams
17

Der Hauptteil besteht darin, die Tausendertrennzeichen einzufügen, was folgendermaßen geschehen könnte:

<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)));">
Roenving
quelle
Ich erhalte eine falsche Zahlenausgabe, wenn ich negative Werte in ins1000Sep () eingebe.
Peter
16

Es gibt ein eingebautes function toFixed injavascript

var num = new Number(349);
document.write("$" + num.toFixed(2));
Tor
quelle
Diese Antwort sieht überflüssig aus. Crushs Antwort wurde bereits erwähnttoFixed()
Ian Dunn,
3
toFixed()ist eine Funktion des NumberObjekts und funktioniert nicht, var numwenn es eine war String, daher hat mir der zusätzliche Kontext geholfen.
Timborden
15
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;
}

Von WillMaster .

Bill die Eidechse
quelle
Klein und einfach. Vielen Dank.
Connor Simpson
1
einfach, aber kein Komma für 1.000
Aron
15

Ich schlage die NumberFormat-Klasse aus der Google Visualization API vor .

Sie können so etwas tun:

var formatter = new google.visualization.NumberFormat({
    prefix: '$',
    pattern: '#,###,###.##'
});

formatter.formatValue(1000000); // $ 1,000,000

Ich hoffe, es hilft.

juanchopx2
quelle
14

Dies mag etwas spät sein, aber hier ist eine Methode, die ich gerade für einen Kollegen ausgearbeitet habe, um ein Gebietsschema hinzuzufügen .toCurrencyString() allen Zahlen Funktion berücksichtigt. Die Internalisierung dient nur der Nummerngruppierung, NICHT dem Währungszeichen. Wenn Sie Dollar ausgeben, verwenden Sie diese "$"wie angegeben, da $123 4567in Japan oder China dieselbe USD-Zahl wie $1,234,567hier in den USA vorhanden ist. Wenn Sie Euro / etc. Ausgeben, ändern Sie das Währungszeichen von "$".

Deklarieren Sie dies irgendwo in Ihrem KOPF oder wo immer nötig, kurz bevor Sie es verwenden müssen:

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

Dann bist du fertig! Verwenden (number).toCurrencyString()Sie diese Option überall dort, wo Sie die Nummer als Währung ausgeben müssen.

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

Wie gewöhnlich gibt es mehrere Möglichkeiten, dasselbe zu tun, aber ich würde es vermeiden, es zu verwenden Number.prototype.toLocaleString es zu verwenden da es je nach Benutzereinstellungen unterschiedliche Werte zurückgeben kann.

Ich empfehle auch nicht, die Number.prototypePrototypen von nativen Objekten zu erweitern. Dies ist eine schlechte Praxis, da dies zu Konflikten mit dem Code anderer Personen (z. B. Bibliotheken / Frameworks / Plugins) führen kann und möglicherweise nicht mit zukünftigen JavaScript-Implementierungen / -Versionen kompatibel ist.

Ich glaube, dass reguläre Ausdrücke der beste Ansatz für das Problem sind. Hier ist meine Implementierung:

/**
 * 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);
    }
}

bearbeitet am 30.08.2010: Option zum Festlegen der Anzahl der Dezimalstellen hinzugefügt. bearbeitet am 23.08.2011: Option hinzugefügt, um die Anzahl der Dezimalstellen auf Null zu setzen.

Miller Medeiros
quelle
Der Punkt von toLocaleString ist, dass es sich an die Einstellungen des Benutzers anpasst.
Joseph Lennox
11

Hier sind einige Lösungen, die alle die Testsuite, die Testsuite und den Benchmark bestehen. Wenn Sie zum Testen kopieren und einfügen möchten, probieren Sie This Gist aus .

Methode 0 (RegExp)

Basieren Sie auf https://stackoverflow.com/a/14428340/1877620 , aber korrigieren Sie, wenn kein Dezimalpunkt vorhanden ist.

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

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

Methode 2 (Auf Array teilen)

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

Methode 3 (Schleife)

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

Anwendungsbeispiel

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

Separator

Wenn wir ein benutzerdefiniertes Tausender- oder Dezimaltrennzeichen möchten, verwenden Sie replace():

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

Testsuite

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();
Steely Wing
quelle
Verbessert von Ihrer Methode 2. Wechseln Sie von var a = this.toFixed (Genauigkeit) .split ('.') Zu var multiplier = Math.pow (10, Genauigkeit + 1), WholeNumber = Math.floor (dieser * Multiplikator). ;; var a = Math.round (ganze Zahl / 10) * 10 / Multiplikator; if (String (a) .indexOf ('.') <1) {a + = '.00'; } a = String (a) .split ('.'), toFixed nicht verwenden, da es fehlerhaft ist.
Vee
console.log (parseFloat ('4.835'). toFixed (2)); > 4.83 console.log (parseFloat ('54 .835 '). ToFixed (2)); > 54.84 console.log (parseFloat ('454.835'). ToFixed (2)); > 454.83 console.log (parseFloat ('8454.835'). ToFixed (2)); > 8454.83 Alle Dezimalstellen dieser Werte sollten .84 und nicht .83 sein
siehe
11

Number(value)
        .toFixed(2)
        .replace(/(\d)(?=(\d{3})+(?!\d))/g, "$1,")

Adam Pery
quelle
10

Eine einfache Option für die korrekte Platzierung von Kommas, indem Sie zuerst die Zeichenfolge und den regulären regulären Ausdruck umkehren.

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

Ich fand dies von: accounting.js . Es ist sehr einfach und passt perfekt zu meinen Bedürfnissen.

// 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€ 

Faysal Haque
quelle
$('#price').val( accounting.formatMoney(OOA, { symbol: "€", precision: 2,thousand: ".", decimal :",",format: "%v%s" } ) );- zeigen 1.000,00 E