
前言
最近剛好有一個需求要把數字格式化成千分位或貨幣格式,剛好就寫一下這一篇該如何實現這個需求。
千分位格式化
通常我們在做一些金流或報表時,會需要將數字格式化成千分位,而方式有很多種:
1 2 3
| const number = 1234567.89; const formattedNumber = number.toLocaleString('en-US'); console.log(formattedNumber);
|
這個方法會根據指定的地區格式化數字,'en-US' 代表美國格式,會使用逗號作為千分位分隔符。
但如果你想要自訂分隔符號,可以使用正則表達式:
1 2 3 4 5 6 7
| function formatNumberWithCommas(number) { return number.toString().replace(/\B(?=(\d{3})+(?!\d))/g, "."); }
const number = 1234567.89; const formattedNumber = formatNumberWithCommas(number); console.log(formattedNumber);
|
這個函式會將數字轉換成字串,然後使用正則表達式在每三位數前插入指定的分隔符號(這裡用的是 .)。
但如果今天想要在數字前面加上貨幣符號,可以這樣做:
1 2 3 4 5 6 7
| function formatCurrency(number, currencySymbol = '$') { return currencySymbol + number.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ","); }
const number = 1234567.89; const formattedCurrency = formatCurrency(number, 'NT$'); console.log(formattedCurrency);
|
其實可以發現不管是千分位或貨幣格式化,都是利用正則表達式來達成的。
如果不使用上述的方法,則是可能會改用 numeral 這個套件來處理,但…這個套件已經沒有在維護且較老舊,許多人會乾脆自己寫。
傳統方法雖然可行,但不夠直覺與易維護,那…到底有沒有更符合現代 JavaScript 的寫法呢?答案是有的,那就是使用 Intl.NumberFormat。
現代開發更推薦用內建的 Intl.NumberFormat,因為效能好又免安裝,下面是它的基本用法:
1 2
| const formatter = new Intl.NumberFormat(locales, options); formatter.format(number);
|
locales: 用來指定地區,例如 'en-US'、'zh-TW' 等等。
options: 用來指定格式化選項,例如 style、currency、minimumFractionDigits 等等。
Intl.NumberFormat 是一個專門用來格式化數字的 JavaScript 內建物件,可以非常方便地處理各種數字格式化需求,底下是一個範例:
1 2 3 4 5 6 7
| const number = 1234567.89; const formatter = new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD', }); const formattedCurrency = formatter.format(number); console.log(formattedCurrency);
|
你可以看到這個方法不僅可以處理千分位,還可以直接處理貨幣符號,不用再自己去寫正規表達式,而且可以根據不同的地區自動調整格式,非常方便。
如果你想要格式化成其他貨幣,只需要更改 currency 的值即可,例如:
1 2 3 4 5 6 7
| const number = 1234567.89; const formatter = new Intl.NumberFormat('ja-JP', { style: 'currency', currency: 'JPY', }); const formattedCurrency = formatter.format(number); console.log(formattedCurrency);
|
這樣就可以輕鬆地將數字格式化成日圓的格式。
options
options 本身還有很多其他的選項可以使用,以下是一些常用的選項:
- style: 指定格式化的樣式
'decimal': 十進位格式(預設值)
'currency':貨幣格式
'percent':百分比格式
- currency: 指定貨幣的類型(例如
'USD'、'EUR'、'JPY' 等等),這個選項只有在 style 設為 'currency' 時才需要設定。
- currencyDisplay: 指定貨幣符號的顯示方式
'symbol':顯示貨幣符號(例如 $、€、¥ 等等)
'code':顯示貨幣代碼(例如 USD、EUR、JPY 等等)
'name':顯示貨幣名稱(例如 US Dollar、Euro、Japanese Yen 等等)
- minimumIntegerDigits: 指定整數部分的最小位數,如果不足會在前面補零。
- minimumFractionDigits: 指定小數部分的最小位數,如果不足會在後面補零。
- maximumFractionDigits: 指定小數部分的最大位數,如果超過會進行四捨五入。
- minimumSignificantDigits: 指定有效數字的最小位數。
- maximumSignificantDigits: 指定有效數字的最大位數。
範例
接下來底下我也條列一下每一個選項的範例:
style
要把數字用什麼來格式化:
1 2 3 4 5 6 7 8 9 10 11
| new Intl.NumberFormat('zh-TW', { style: 'decimal' }).format(1234567.89);
new Intl.NumberFormat('zh-TW', { style: 'currency', currency: 'TWD' }).format(1234567.89);
new Intl.NumberFormat('zh-TW', { style: 'percent' }).format(0.123);
|
currency
當 style: 'currency' 時,指定是哪一種貨幣:
1 2 3 4 5 6 7 8
| new Intl.NumberFormat('zh-TW', { style: 'currency', currency: 'USD' }).format(1234.5);
new Intl.NumberFormat('zh-TW', { style: 'currency', currency: 'JPY' }).format(1234.5);
new Intl.NumberFormat('zh-TW', { style: 'currency', currency: 'EUR' }).format(1234.5);
|
currencyDisplay
決定貨幣怎麼顯示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| new Intl.NumberFormat('zh-TW', { style: 'currency', currency: 'USD', currencyDisplay: 'symbol' }).format(1234);
new Intl.NumberFormat('zh-TW', { style: 'currency', currency: 'USD', currencyDisplay: 'code' }).format(1234);
new Intl.NumberFormat('zh-TW', { style: 'currency', currency: 'USD', currencyDisplay: 'name' }).format(1234);
new Intl.NumberFormat('zh-TW', { style: 'currency', currency: 'USD', currencyDisplay: 'narrowSymbol' }).format(1234);
|
Note
不同瀏覽器 / Node.js 版本 / ICU 資料 會影響結果。如果想要保證輸出 NT$,可以額外指定 currencyDisplay: ‘narrowSymbol’ 或手動處理。
minimumIntegerDigits
設定整數部分至少幾位,不足補 0:
1 2 3 4 5 6
| new Intl.NumberFormat('zh-TW', { minimumIntegerDigits: 3 }).format(7);
new Intl.NumberFormat('zh-TW', { minimumIntegerDigits: 5 }).format(123);
|
minimumFractionDigits
小數部分最少顯示幾位:
1 2 3 4 5
| new Intl.NumberFormat('zh-TW', { minimumFractionDigits: 2 }).format(5);
new Intl.NumberFormat('zh-TW', { minimumFractionDigits: 4 }).format(5.1);
|
maximumFractionDigits
小數部分最多顯示幾位(多的會四捨五入):
1 2 3 4 5
| new Intl.NumberFormat('zh-TW', { maximumFractionDigits: 2 }).format(5.6789);
new Intl.NumberFormat('zh-TW', { maximumFractionDigits: 0 }).format(5.9);
|
minimumSignificantDigits
有效數字最少幾位,不足補 0:
1 2 3 4 5
| new Intl.NumberFormat('zh-TW', { minimumSignificantDigits: 3 }).format(7);
new Intl.NumberFormat('zh-TW', { minimumSignificantDigits: 5 }).format(123);
|
maximumSignificantDigits
有效數字最多多少位,多的會四捨五入。
1 2 3 4 5
| new Intl.NumberFormat('zh-TW', { maximumSignificantDigits: 3 }).format(12345);
new Intl.NumberFormat('zh-TW', { maximumSignificantDigits: 4 }).format(0.0012345);
|
整理這些技術筆記真的很花時間,如果你願意 關閉 Adblock 支持我,我會把這份感謝轉換成更多「踩坑轉避坑」的內容給你!ヽ(・∀・)ノ
Advertisement