欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JavaScript面對(duì)國(guó)際化編程時(shí)的一些建議

 更新時(shí)間:2015年06月24日 11:10:47   投稿:goldensun  
這篇文章主要介紹了JavaScript面對(duì)國(guó)際化編程時(shí)的一些建議,包括時(shí)區(qū)與語(yǔ)言編碼等一些值得注意的問(wèn)題,需要的朋友可以參考下

什么是國(guó)際化?

國(guó)際化(Internationalization的縮寫(xiě)是i18n——i,中間18個(gè)字符,n)是將軟件處理的能讓來(lái)自各種地方使用各種語(yǔ)言的用戶更簡(jiǎn)單使用的一個(gè)過(guò)程。假定某個(gè)用戶來(lái)自某個(gè)地方說(shuō)某種語(yǔ)言,他可能不經(jīng)意間就得到一些錯(cuò)誤提示。尤其是你甚至都沒(méi)有做這種假設(shè)。
 

function formatDate(d)
{
 // Everyone uses month/date/year...right?
 var month = d.getMonth() + 1;
 var date = d.getDate();
 var year = d.getFullYear();
 return month + "/" + date + "/" + year;
}
 
function formatMoney(amount)
{
 // All money is dollars with two fractional digits...right?
 return "$" + amount.toFixed(2);
}
 
function sortNames(names)
{
 function sortAlphabetically(a, b)
 {
 var left = a.toLowerCase(), right = b.toLowerCase();
 if (left > right)
  return 1;
 if (left === right)
  return 0;
 return -1;
 }
 
 // Names always sort alphabetically...right?
 names.sort(sortAlphabetically);
}

 
JavaScript過(guò)去的i18n支持太糟糕

傳統(tǒng)JS的i18n程序使用toLocaleString()方法進(jìn)行格式化。結(jié)果字符串包含實(shí)現(xiàn)自身提供的所有細(xì)節(jié):沒(méi)有辦法自己選擇(你確實(shí)需要那種date格式的weekday嗎?year是無(wú)關(guān)緊要的嗎?)。即使包含對(duì)應(yīng)的細(xì)節(jié),格式也可能是錯(cuò)的,比如本期望是百分比但得到的是數(shù)字。而且你還不能選擇一個(gè)區(qū)域設(shè)置(locale)。

對(duì)于排序,JS提供了基本沒(méi)用的基于區(qū)域設(shè)置(locale-sensitive)的文本比較函數(shù)。localeCompare()確實(shí)存在,但是其接口根本不適合sort。而且還不允許選擇區(qū)域設(shè)置,或者排序方式。

這些限制太糟了(當(dāng)我認(rèn)識(shí)到時(shí),我非常吃驚!),因?yàn)樾枰猧18n支持(通常是金融站點(diǎn)用于顯示貨幣)的嚴(yán)謹(jǐn)web應(yīng)用會(huì)把數(shù)據(jù)打包,發(fā)給服務(wù)器,服務(wù)器進(jìn)行操作,然后發(fā)回客戶端。數(shù)據(jù)往返服務(wù)器僅僅為了處理貨幣的數(shù)量。Yeesh。

新的JS國(guó)際化API

新的ECMAScript國(guó)際化API大大提升了JS的i18n能力。 它提供了大家所能想到的格式化date、數(shù)字,文本排序的方式。區(qū)域設(shè)置是可選的,如果請(qǐng)求的區(qū)域設(shè)置不支持可以回退。格式化請(qǐng)求可以指定具體要包含的組件。支持自定義的百分比、有效數(shù)字、貨幣格式。開(kāi)放了大量排序選項(xiàng)用于文本排序。如果你關(guān)心性能,首要的操作是選擇一個(gè)區(qū)域設(shè)置,然后處理選項(xiàng)參數(shù),現(xiàn)在這個(gè)操作只會(huì)處理一次,而不是之前每次區(qū)域設(shè)置相關(guān)的操作執(zhí)行時(shí)都會(huì)被執(zhí)行一遍。

這不是說(shuō),這個(gè)API是萬(wàn)能藥,而僅僅是"盡最大努力"。精確的輸出幾乎總是故意不指定的。一份實(shí)現(xiàn)可以僅支持 oj 區(qū)域設(shè)置(合法的),也可以忽略(幾乎全部)提供的格式化選項(xiàng)。大多數(shù)實(shí)現(xiàn)都包含高質(zhì)量的多區(qū)域支持,但并不保證有(尤其是資源限定的系統(tǒng),如手機(jī))。

在底層,F(xiàn)irefox的實(shí)現(xiàn)依賴于Unicode 的國(guó)際化組件庫(kù)(ICU) ,這個(gè)庫(kù)又依賴 Unicode Common 區(qū)域數(shù)據(jù)倉(cāng)庫(kù)(CLDR)的區(qū)域數(shù)據(jù)集。我們的實(shí)現(xiàn)是自托管的:ICU之上的大部分實(shí)現(xiàn)用JS寫(xiě)的。在這個(gè)過(guò)程中,我們遇到了一些問(wèn)題(我們從未如此大規(guī)模的自托管過(guò)),但基本上都不大。

Intl 接口(不是數(shù)字1,是字母l)

i18n 存在于 Intl 對(duì)象之上。Intl 包含3個(gè)構(gòu)造函數(shù):Intl.Collator, Intl.DateTimeFormat, 和Intl.NumberFormat。每個(gè)構(gòu)造函數(shù)創(chuàng)建一個(gè)對(duì)象,這個(gè)對(duì)象提供相關(guān)操作、高效地為這些操作緩存區(qū)域設(shè)置和選項(xiàng)。按以下方式創(chuàng)建對(duì)象:
 

var ctor = "Collator"; // 或其他 
var instance = new Intl[ctor](locales, options);

locales 是個(gè)字符串,指定單個(gè)語(yǔ)言標(biāo)簽,或者包含多個(gè)語(yǔ)言標(biāo)簽的類數(shù)組對(duì)象。語(yǔ)言標(biāo)簽如下面的字符串:en(普通英語(yǔ)),de-AT(奧地利德語(yǔ)),zh-Hant-TW(臺(tái)灣使用的繁體中文)。語(yǔ)言標(biāo)簽可以包含一個(gè)“Unicode擴(kuò)展”,形式為-u-key1-value1-key2-value2..., 其中每個(gè)key是“擴(kuò)展key”。不同的構(gòu)造函數(shù)對(duì)此進(jìn)行具體解釋。

opions 是個(gè)對(duì)象,其屬性(如果不存在,就賦值為undefined)決定格式化器(formatter)和整理器(collator)的行為。精確的解釋由構(gòu)造函數(shù)決定。


給定區(qū)域信息和選項(xiàng),實(shí)現(xiàn)會(huì)嘗試生成近似理想行為的最接近行為。Firefox 支持用于整理(collation)的400+區(qū)域,用于date/time和數(shù)字格式化的600+區(qū)域,所以很可能(但不保證)你想要的區(qū)域是被支持的。

Intl 通常不保證某些特定行為。如果請(qǐng)求的區(qū)域不被支持,Intl 允諾“盡最大努力”的行為。即使區(qū)域是被支持的,行為也不是嚴(yán)格指定的。永遠(yuǎn)不要假設(shè)特定的選項(xiàng)集適用于某個(gè)特定格式。(圍繞請(qǐng)求的組件)總體格式的用語(yǔ)可能因?yàn)g覽器甚至瀏覽器的版本而不同。單個(gè)組件的格式是未指定的:weekday的短格式可以為“S”, “Sa”, 或“Sat”。Intl API并不用于公開(kāi)精確的特定行為。

選項(xiàng)

date/time格式化的主要選項(xiàng)屬性如下:

  •     weekday, era

    "narrow", "short", or "long".  (era通常指歷法系統(tǒng)中長(zhǎng)于一年的分段,如現(xiàn)行日皇統(tǒng)治, 或者其他紀(jì)年法)

  •     month

    "2-digit", "numeric", "narrow", "short", or "long"

  •     year
  •     day
  •     hour, minute, second

    "2-digit" or "numeric"

  •     timeZoneName

    "short" or "long"

  •     timeZone

    區(qū)分大小寫(xiě)的"UTC"通過(guò)對(duì)應(yīng)的toUTC進(jìn)行格式化。有些值如"CEST"和"America/New_York"不是必須被支持的,它們確實(shí)在當(dāng)前Firefox下沒(méi)有效果。

這些值并不映射到特定格式:記住Intl API幾乎不指定精確的行為。Intl的目的,舉例來(lái)說(shuō)是"narrow", "short", 和"long"生成對(duì)應(yīng)大小的“S”/“Sa”, “Sat”, 和“Saturday”(輸出可能不太準(zhǔn)確,因?yàn)镾aturday和Sunday都可以生成“S”)。  "2-digit"和"numeric"映射到2位數(shù)字的字符串或者全長(zhǎng)度的數(shù)字字符串,如“70”和“1970”。

最終使用的選項(xiàng)大部分是請(qǐng)求的選項(xiàng)。但是,如果你不指定請(qǐng)求的 weekday/year/month/day/hour/minute/second,那么 year/month/day 將會(huì)被加入到你提供的選項(xiàng)。


除此之外,還有些特殊的選項(xiàng):

  •     hour12

    指定hour采用12小時(shí)還是24小時(shí)格式。默認(rèn)通常是依賴于區(qū)域設(shè)置的(某些細(xì)節(jié),如午夜是0點(diǎn),還是12點(diǎn),以及是否存在前導(dǎo)0,都是依賴于區(qū)域設(shè)置的)。

還有另外2種特殊屬性,localeMatcher (可選"lookup"或"best fit") 和formatMatcher (可選"basic"或"best fit"),兩者默認(rèn)值都是"best fit"。這些會(huì)影響正確的區(qū)域設(shè)置和格式的選取。它們的用例可能比較難懂,就不贅述了。
區(qū)域設(shè)置相關(guān)選項(xiàng)

DateTimeFormat也允許通過(guò)自定義歷法和數(shù)字系統(tǒng)來(lái)格式化。具體細(xì)節(jié)存在于區(qū)域設(shè)置,所以它們可以在語(yǔ)言標(biāo)簽的Unicode擴(kuò)展中找到。


例如,泰國(guó)的泰語(yǔ)中語(yǔ)言標(biāo)簽為th-TH?;匾幌耈nicode擴(kuò)展的格式-u-key1-value1-key2-value2....  歷法系統(tǒng)的key是ca, 數(shù)字系統(tǒng)的key時(shí)nu。泰語(yǔ)數(shù)字系統(tǒng)值為thai,中文歷法系統(tǒng)值為chinese。因此用大體這樣的方式來(lái)格式化date,我們把包含這些key/value對(duì)的Unicode追加到語(yǔ)言標(biāo)簽上去:th-TH-u-ca-chinese-nu-thai。

關(guān)于更多歷法和數(shù)字系統(tǒng)的信息,查看DateTimeFormat的完整文檔。
舉例

創(chuàng)建DateTimeFormat對(duì)象后,下一步是通過(guò)方便的format()函數(shù)來(lái)格式化date。更方便的是,這個(gè)函數(shù)是有界函數(shù)(bound function):你不必在DateTimeFormat上直接調(diào)用。之后給它傳遞一個(gè)時(shí)間戳或者Date對(duì)象。


總結(jié)一下,下文是如何為特定用途創(chuàng)建DateTimeFormat選項(xiàng)的例子(在當(dāng)前Firefox執(zhí)行行為下)。
 

var msPerDay = 24 * 60 * 60 * 1000; 
 
// July 17, 2014 00:00:00 UTC.
var july172014 = new Date(msPerDay * (44 * 365 + 11 + 197));

我們來(lái)格式化美國(guó)英語(yǔ)的date。我們先創(chuàng)建一個(gè)2位數(shù)字的month/day/year, 加上2位數(shù)字的hours/minutes, 還有一個(gè)短時(shí)區(qū)來(lái)確定這個(gè)時(shí)間。(結(jié)果肯定因不同時(shí)區(qū)而明顯不同)
 

var options =
 { year: "2-digit", month: "2-digit", day: "2-digit",
 hour: "2-digit", minute: "2-digit",
 timeZoneName: "short" };
var americanDateTime =
 new Intl.DateTimeFormat("en-US", options).format; 
 
print(americanDateTime(july172014)); // 07/16/14, 5:00 PM PDT

或者類似的,對(duì)葡萄牙語(yǔ),最好是巴西使用的葡語(yǔ),但是用在葡萄牙作品中的。格式會(huì)稍長(zhǎng),因?yàn)榘暾膟ear和正式拼寫(xiě)的month,但是因移植性要轉(zhuǎn)成UTC格式。
 

var options =
 { year: "numeric", month: "long", day: "numeric",
 hour: "2-digit", minute: "2-digit",
 timeZoneName: "short", timeZone: "UTC" };
var portugueseTime =
 new Intl.DateTimeFormat(["pt-BR", "pt-PT"], options); 
 
// 17 de julho de 2014 00:00 GMT
print(portugueseTime.format(july172014));

那對(duì)于一個(gè)壓縮的,UTC格式的瑞士火車(chē)每周調(diào)度表?我們嘗試用正式語(yǔ)言按流行度從大到小來(lái)選擇最易讀的一個(gè)。
 

var swissLocales = ["de-CH", "fr-CH", "it-CH", "rm-CH"];var options =
 { weekday: "short",
 hour: "numeric", minute: "numeric",
 timeZone: "UTC", timeZoneName: "short" };
var swissTime =
 new Intl.DateTimeFormat(swissLocales, options).format; 
 
print(swissTime(july172014)); // Do. 00:00 GMT

或者我們嘗試某個(gè)日本博物館里的一幅畫(huà)中的描述性文本中的date,這個(gè)date使用日本的year和era歷法。
 

var jpYearEra =
 new Intl.DateTimeFormat("ja-JP-u-ca-japanese",
       { year: "numeric", era: "long" }); 
 
print(jpYearEra.format(july172014)); // 平成26年

對(duì)一些完全不同的、更長(zhǎng)的date,用于泰國(guó)泰語(yǔ),但是使用泰語(yǔ)數(shù)字系統(tǒng)和中國(guó)歷法。(類似Firefox的高質(zhì)量實(shí)現(xiàn)通常會(huì)將普通的th-TH當(dāng)做th-TH-u-ca-buddhist-nu-latn, 因?yàn)樘﹪?guó)使用佛歷系統(tǒng)和拉丁0-9數(shù)字)。
 

var options =
 { year: "numeric", month: "long", day: "numeric" };
var thaiDate =
 new Intl.DateTimeFormat("th-TH-u-nu-thai-ca-chinese", options); 
 
print(thaiDate.format(july172014)); // ?? 6 ??

撇開(kāi)歷法和數(shù)字系統(tǒng),還是很簡(jiǎn)單的。只要選取自己的組件和長(zhǎng)度。
 
選項(xiàng)

數(shù)字格式化的主要選項(xiàng)屬性有:

  •     style

    "currency", "percent", or "decimal" (默認(rèn)值).

  •     currency

    3字母貨幣代碼,如USD、CHF。需要style是"currency", 不然沒(méi)有意義

  •     currencyDisplay

    "code", "symbol", or "name", 默認(rèn)為"symbol".  "code"使用格式字符串的3字母貨幣代碼。"symbol"使用貨幣符號(hào),如$或£。"name"通常使用某些正式拼寫(xiě)版本的貨幣。(Firefox 目前僅支持"symbol", 這個(gè)問(wèn)題不就就修復(fù))

  •     minimumIntegerDigits

    范圍1到21(包含)的整數(shù),默認(rèn)為1。結(jié)果字符串的整數(shù)部分如果沒(méi)有這么長(zhǎng),它前面會(huì)用0來(lái)填充。  (若這個(gè)值為2,那么3的格式化形式為“03”。)

  •     minimumFractionDigits, maximumFractionDigits

    0-20(包含)的整數(shù)。結(jié)果字符串至少minimumFractionDigits, 至多maximumFractionDigits個(gè)有效數(shù)字。如果style是"currency",默認(rèn)最小值跟貨幣有關(guān)(通常是2,很少0或者3),不然就是0。默認(rèn)最大值,百分比是0,數(shù)字是3,貨幣的最大值跟貨幣有關(guān)。

  •     minimumSignificantDigits, maximumSignificantDigits

    1-21(包含)的整數(shù)。如果有,它們將會(huì)覆蓋上文關(guān)于整數(shù)/分?jǐn)?shù)的對(duì)數(shù)字的控制,而由它們以及數(shù)字的要求長(zhǎng)度,共同確定格式化的數(shù)字字符串中最小/最大有效數(shù)字的值。 (注意對(duì)10的倍數(shù),有效數(shù)字可能不準(zhǔn)確,如100,它的1,2,3位有效數(shù)字。)

  •     useGrouping

    布爾值(默認(rèn)true)決定格式化字符串是否包含分組分隔符(如,英語(yǔ)的千分隔符“,”)。

NumberFormat還識(shí)別難懂的、大多數(shù)可忽略的localeMatcher屬性。


區(qū)域化選項(xiàng)

在Unicode擴(kuò)展中,使用nu關(guān)鍵字可以使DateTimeFormat支持自定義數(shù)字系統(tǒng),NumberFormat也是這樣。 例如,在中國(guó),中文的語(yǔ)言標(biāo)簽是zh-CN。 漢語(yǔ)十進(jìn)制數(shù)字系統(tǒng)對(duì)應(yīng)的值是hanidec。 為了格式化這些系統(tǒng)的數(shù)字,我們?cè)谶@些語(yǔ)言標(biāo)簽上添加一些Unicode擴(kuò)展:zh-CN-u-nu-hanidec。

關(guān)于不同數(shù)字系統(tǒng)標(biāo)識(shí)的完整信息,見(jiàn)NumberFormat詳細(xì)說(shuō)明文檔。

示例

NumberFormat對(duì)象有一個(gè) format方法,這一點(diǎn)和 DateTimeFormat相同。 format方法是一個(gè)有界函數(shù),它有時(shí)可以獨(dú)立于 NumberFormat使用。


下面是在當(dāng)前Firefox環(huán)境下為特定用途創(chuàng)建NumberFormat選項(xiàng)的例子。首先,我們來(lái)格式化中國(guó)大陸中文的貨幣格式,特別是使用漢字?jǐn)?shù)字(而不是更普遍的拉丁數(shù)字)。選擇"currency" style, 然后使用renminbi(yuan)的貨幣代碼,數(shù)字分組默認(rèn),小數(shù)部分?jǐn)?shù)字采用通常做法。
 

var tibetanRMBInChina =
 new Intl.NumberFormat("zh-CN-u-nu-hanidec",
      { style: "currency", currency: "CNY" }); 
print(tibetanRMBInChina.format(1314.25)); // ¥ 一,三一四.二五

或者我們來(lái)格式化美國(guó)的天然氣價(jià)格,千分位有個(gè)古怪的9,用在美國(guó)英語(yǔ)中。
 

var gasPrice =
 new Intl.NumberFormat("en-US",
      { style: "currency", currency: "USD",
       minimumFractionDigits: 3 }); 
print(gasPrice.format(5.259)); // $5.259

或者我們嘗試埃及的阿拉伯語(yǔ)中的百分比。確定百分比有至少2個(gè)有效數(shù)字。(注意這個(gè)以及其他RTL例子可能在RTL上下文出現(xiàn)的順序不一樣,如?????? 而不是??????,RTL/right to left,從右到左的)
 

var arabicPercent =
 new Intl.NumberFormat("ar-EG",
      { style: "percent",
       minimumFractionDigits: 2 }).format; 
print(arabicPercent(0.438)); // ??????

或者假設(shè)我們格式化阿富汗波斯語(yǔ),我們期望至少2位的整數(shù)部分,至多2位的小數(shù)部分。
 

var persianDecimal =
 new Intl.NumberFormat("fa-AF",
      { minimumIntegerDigits: 2,
       maximumFractionDigits: 2 }); 
print(persianDecimal.format(3.1416)); // ?????

最后,我們格式化巴林的阿拉伯語(yǔ)中的巴林第納爾的數(shù)量。不同于大部分貨幣,巴林第納爾等于1000費(fèi)爾,因此我們需要三位小數(shù)位。(再次注意,不要太過(guò)相信表面的閱讀順序)?
 

var bahrainiDinars =
 new Intl.NumberFormat("ar-BH",
      { style: "currency", currency: "BHD" }); 
print(bahrainiDinars.format(3.17)); // ?.?.? ?????

整理
選項(xiàng)

下面是整理的主要選項(xiàng)屬性:

  •     usage

    "sort" or "search" (默認(rèn)"sort"), 指定整理器(collator)的目的。(查找整理器可能比排序整理器更多考慮字符串是否相等。)

  •     sensitivity/敏感性

    "base", "accent", "case", or "variant"。這個(gè)選項(xiàng)影響整理器對(duì)基本字符相同但是重音/變音不同的字符的敏感性。(基本字符與區(qū)域設(shè)置有關(guān):“a”和“?”在德語(yǔ)中基本字符相同,但是瑞典語(yǔ)中是不同的。)  "base"敏感性只考慮基本字符,忽略各種變體(如德語(yǔ)中“a”, “A”,和“?”被認(rèn)為是相同的)。 "accent"敏感性考慮基本字符和重音,但是忽略大小寫(xiě)(如德語(yǔ)中的“a和“A”是相同的,“?”與兩者不同)。"case"考慮基本字符和大小寫(xiě),而忽略重音(如德語(yǔ)中的“a”和“?”相同,而與“A”不同)。"variant"考慮基本字符、重音、大小寫(xiě)(如德語(yǔ)的“a”, “?”和“A”均不同)。如果usage是"sort",默認(rèn)"variant"; 否則與區(qū)域設(shè)置有關(guān)。

  •     numeric

    默認(rèn)false的布爾值,決定字符串中的數(shù)字是否被當(dāng)做數(shù)字參與比較。如當(dāng)做數(shù)字的排序結(jié)果可能是"F-4 Phantom II", "F-14 Tomcat", "F-35 Lightning II"; 不當(dāng)做數(shù)字的結(jié)果"F-14 Tomcat", "F-35 Lightning II", "F-4 Phantom II".

  •     caseFirst

    "upper", "lower", or "false" (默認(rèn))。決定比較時(shí)是否考慮大小寫(xiě):"upper"把大寫(xiě)放在前面("B", "a", "c"), "lower"把小寫(xiě)放前面("a", "c", "B"), "false"完全忽略大小寫(xiě)("a", "B", "c")。 (注意,目前Firefox完全忽略這個(gè)屬性)

  •     ignorePunctuation

    默認(rèn)false的布爾值。決定比較時(shí)是否忽略標(biāo)點(diǎn)(如"biweekly"和"bi-weekly"是否相等)。

localeMatcher屬性你可以忽略了。

區(qū)域相關(guān)選項(xiàng)

區(qū)域的Unicode擴(kuò)展部分指定的整理器主要選項(xiàng)是co,它選擇排序操作的方式:電話本(phonebk), 字典 (dict), 還有其他。

另外,kn和kf這兩個(gè)key可以選擇拷貝選項(xiàng)對(duì)象的numeric和caseFirst屬性。但是并不保證可用于語(yǔ)言標(biāo)簽,而且選項(xiàng)比語(yǔ)言標(biāo)簽的組件更清晰。所以最好在選項(xiàng)內(nèi)部進(jìn)行調(diào)整。

key-value對(duì)(paris)嵌入到Unicode的方式跟DateTimeFormat和NumberFormat相同; 想知道如何在語(yǔ)言標(biāo)簽中指定它們,可以查看對(duì)應(yīng)的章節(jié)。

舉例

整理器Collator對(duì)象有個(gè)比較函數(shù)屬性。這個(gè)函數(shù)接受2個(gè)參數(shù)x和y, 如果x<y返回負(fù)值,x>y返回正值,x==y返回0。對(duì)于格式化函數(shù),比較是個(gè)有界函數(shù)(bound function),可以抽取出來(lái)做其他用途。

我們嘗試來(lái)給德國(guó)德語(yǔ)的姓氏進(jìn)行排序。德語(yǔ)中實(shí)際上有2種排序方式,電話本和字典。電話本排序強(qiáng)調(diào)讀音,比如“?”, “?”等近似被擴(kuò)展成“ae”, “oe”等。
 

var names =
 ["Hochberg", "H?nigswald", "Holzman"]; 
var germanPhonebook = new Intl.Collator("de-DE-u-co-phonebk"); 
 
//就像對(duì)["Hochberg", "Hoenigswald", "Holzman"]排序
// Hochberg, H?nigswald, Holzman
print(names.sort(germanPhonebook.compare).join(", "));

有些德語(yǔ)單詞使用變音符進(jìn)行詞形變化,所以在字典中排序會(huì)忽略變音符(除了兩個(gè)單詞僅僅變音符不同:schon,sch?n)。
 

var germanDictionary = new Intl.Collator("de-DE-u-co-dict"); 
 
//就像對(duì)["Hochberg", "Hoenigswald", "Holzman"]排序
// Hochberg, H?nigswald, Holzman
print(names.sort(germanDictionary.compare).join(", "));

或者我們來(lái)對(duì)美國(guó)英語(yǔ)的Firefox的版本進(jìn)行排序,這些字符串故意打錯(cuò)(大小寫(xiě)不同,隨機(jī)重音,變音標(biāo)記,額外的連字符)。我們希望根據(jù)版本號(hào)進(jìn)行排序,所以要做numeric排序,這樣字符串中的數(shù)字才會(huì)作為數(shù)字參與比較,而不是逐字符的。
 

var firefoxen =
 ["FireF?x 3.6",
 "Fire-fox 1.0",
 "Firefox 29",
 "Fírefox 3.5",
 "Fírefox 18"]; 
var usVersion =
 new Intl.Collator("en-US",
     { sensitivity: "base",
      numeric: true,
      ignorePunctuation: true }); 
 
// Fire-fox 1.0, Fírefox 3.5, FireF?x 3.6, Fírefox 18, Firefox 29
print(firefoxen.sort(usVersion.compare).join(", "));

最后,我們來(lái)做跟區(qū)域有關(guān)的字符串查找,查找忽略大小寫(xiě)和重音,并用于美國(guó)英語(yǔ)。

 

// Comparisons work with both composed and decomposed forms.
var decoratedBrowsers =
 [
 "A\u0362maya", // A?maya
 "CH\u035Br?me", // CH?r?me
 "Firefóx",
 "sAfàri",
 "o\u0323pERA", // ?pERA
 "I\u0352E",  // I?E
 ]; 
var fuzzySearch =
 new Intl.Collator("en-US",
     { usage: "search", sensitivity: "base" }); 
function findBrowser(browser)
{
 function cmp(other)
 {
 return fuzzySearch.compare(browser, other) === 0;
 }
 return cmp; 
} 
print(decoratedBrowsers.findIndex(findBrowser("Firêfox"))); // 2 
print(decoratedBrowsers.findIndex(findBrowser("Saf?ri"))); // 3 
print(decoratedBrowsers.findIndex(findBrowser("?maya"))); // 0 
print(decoratedBrowsers.findIndex(findBrowser("?pera"))); // 4 
print(decoratedBrowsers.findIndex(findBrowser("Chromè"))); // 1 
print(decoratedBrowsers.findIndex(findBrowser("I?")));  // 5

瑣碎

檢測(cè)某個(gè)操作是否支持特定區(qū)域,或者一個(gè)區(qū)域是否被支持,會(huì)很有用。Intl在每個(gè)構(gòu)造函數(shù)上都提供了supportedLocales()函數(shù),在每個(gè)原型上提供了resolvedOptions()函數(shù)來(lái)公開(kāi)這些信息。
 

var navajoLocales =
 Intl.Collator.supportedLocalesOf(["nv"], { usage: "sort" });
print(navajoLocales.length > 0
  ? "Navajo collation supported"
  : "Navajo collation not supported"); 
var germanFakeRegion =
 new Intl.DateTimeFormat("de-XX", { timeZone: "UTC" });
var usedOptions = germanFakeRegion.resolvedOptions();
print(usedOptions.locale); // de
print(usedOptions.timeZone); // UTC

遺留行為

ES5的toLocaleString和localeCompar函數(shù)之前沒(méi)有特定語(yǔ)義,不接受特定選項(xiàng),基本上沒(méi)有任何用處。因此i18n API根據(jù)Intl操作重組了它們?,F(xiàn)在每個(gè)方法都接受附加的尾隨locales和options參數(shù),它們會(huì)像Intl構(gòu)造函數(shù)一樣被解釋。(除了toLocaleTimeString 和 toLocaleDateString, 如果options沒(méi)有,它們就會(huì)使用不同的默認(rèn)組件)

對(duì)并不關(guān)心精確行為的簡(jiǎn)單應(yīng)用,這沒(méi)關(guān)系,老方法也可以用。但是如果需要更多控制或者多次格式化、比較的話,最好直接使用Intl。

相關(guān)文章

最新評(píng)論