Help us understand the problem. What is going on with this article?

JavaScriptで数値フォーマットする標準API「Intl.NumberFormat」 (カンマ区切り、円・ドル表記、漢数字など)

More than 1 year has passed since last update.

ほぼすべてのブラウザやNode.jsでサポートされている数値をフォーマットするAPI「Intl.NumberFormat」を紹介する記事です。

JavaScriptで数値をカンマ区切りにしたいときにGoogleで検索してみると、正規表現を使っていたり、ループで回して3桁ごとにカンマ付ける実装を紹介する記事を多く見つけました。
しかし、それらは古い記事ということもあり、2018年現在は数値のフォーマットを実装する必要はありません。EcmaScriptで仕様策定されておりほとんどのブラウザやNode.jsで使える関数があるので紹介します。
今回紹介するコードの実行結果はすべてChromeでの結果になります。

TL;DR

Intl

i18nやl10nといった国際化対応するためのAPIです。
詳しくは「Intl - JavaScript|MDN」をお読みください。
EcmaScriptの仕様については「ここ」を読んで下さい。

Intl.NumberFormat

通過や文字など国や地域によって数の表記は違います。このAPIはその国ごとの表記を指定した表記に変換してくれるAPIを提供してくれるオブジェクトです。
詳しくはMDNの記事をお読み下さい。日本語の記事は情報が古いので英語版を参考にしてください。

以下のようにlocaleをコンストラクタの引数に指定することができます。
引数の指定が無い場合は'us-EN'が設定されます。

const formatter = new Intl.NumberFormat('ja-JP');

Intl.NumberFormat.prototype.format

数値を変換する関数です。Intl.NumberFormatのメソッドです。
IEを含むほぼすべてのブラウザで使用可能です。
よく使われそうな例を紹介します。

カンマ区切り

冒頭で説明したカンマ区切りです。3桁ごとに区切って表示する場合に使うことができます。
以下は'ja-JP'を指定していますが、'us-EN'や引数なしでも同じように3桁でカンマ区切りします。

const formatter = new Intl.NumberFormat('ja-JP');
formatter.format(1000);
// => "1,000"

通貨

数値をサクッと円やドル表記したいことはあると思います。
円の表記は以下のようにNumberFormatの第2引数にオブジェクトを渡すことで実現可能です。
第2引数のオプションについてもやはりMDNの「Intl.NumberFormat」に詳しく載っていますので興味ある方はそちらをお読み下さい。

const formatter = new Intl.NumberFormat('ja-JP', {
  style: 'currency',
  currency: 'JPY'
});
formatter.format(1000);
// => "¥1,000"

もちろん、ドルやユーロなども対応しています。

let formatter = new Intl.NumberFormat('us-EN', {
  style: 'currency',
  currency: 'USD'
});
formatter.format(1000);
// => "$1,000.00"

let formatter = new Intl.NumberFormat('de-DE', {
  style: 'currency',
  currency: 'EUR'
});
formatter.format(1000)
// => "1.000,00 €"

漢数字

数値を漢数字の文字列に変換することも可能です。
以下は「中国で使用される簡体字で書かれる中国語の10進数の漢数字」という指定をしています。
zh-Hans-CNまでが「中国で使用される簡体字で書かれる中国語」を指し、u-nu-hanidecが「10進数の漢数字」を指します。

const formatter = new Intl.NumberFormat('zh-Hans-CN-u-nu-hanidec');
formatter.format(1234567890);
// => "一,二三四,五六七,八九〇"

Intl.NumberFormat.prototype.formatToParts

上記のようにformat関数で数値のフォーマットが行えますが、新しいAPIであるformatToPartsに関しても紹介しておきます。

執筆時点(2018/04/15)ではChrome63とFirefox58で使えるようになっています。
Node.jsも次期バージョンのv10では使えます。
EcmaScriptの仕様は「ここ」にあります。

数値のカスタムフォーマットを行うことが可能になります。
formatToPartsの戻り値は{type: string, value: string}のオブジェクトの配列です。

const formatter = new Intl.NumberFormat('ja-JP', {
  style: 'currency',
  currency: 'JPY'
});
formatter.formatToParts(1000);
// => [ { type: 'currency', value: '¥' },
//      { type: 'integer', value: '1' },
//      { type: 'group', value: ',' },
//      { type: 'integer', value: '000' } ]

オブジェクトの配列なので、あとは好き勝手いじることが可能です。
以下はMDNに掲載されている例をJPYにしてみた例です。

const num = 1000;
const formatter = new Intl.NumberFormat('ja-JP', {
  style: 'currency',
  currency: 'JPY'
});
const yen = formatter.formatToParts(num).map(({type, value}) => {
  switch (type) {
    case 'currency': return "<strong>" + value + "</strong>";
    default: return value;
  }
}).reduce((string, part) => {return string + part});
console.log(yen);
// => "<strong>¥</strong>1,000"

最後に

数値のフォーマット関数は標準で用意されているAPIを使いましょう。

補足(2018/04/17)

はてブでSafariで使えないというコメントがあったので補足します。
Intl.NumberFormat.prototype.formatはSafari10から対応しています。
Intl.NumberFormat.prototype.formatToPartsは使えません。
MDNの日本語版のブラウザ対応表が更新されていませんでした。英語版では10から対応と記載がありました。Safari11.1でも確認済みです。
また、MDNのIntl.NumberFormat.prototype.formatの日本語版のSafariのサポートバージョンも更新しておきました。

参考

最後までお読みいただきありがとうございました。不備や質問がございましたらコメント欄に記載またはTwitterで @shisama_ 宛にメンション飛ばして下さい。

shisama
Node.js Core Collaborator. 関西Node学園Organizer.
https://shisama.dev
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした