String.prototype.normalize()

Baseline 已廣泛支援

此特性已非常成熟,可在多種裝置和瀏覽器版本上使用。自 ⁨2016 年 9 月⁩以來,它已在各大瀏覽器中可用。

normalize() 方法用於 String 值,返回此字串的 Unicode 標準化形式。

試一試

const name1 = "\u0041\u006d\u00e9\u006c\u0069\u0065";
const name2 = "\u0041\u006d\u0065\u0301\u006c\u0069\u0065";

console.log(`${name1}, ${name2}`);
// Expected output: "Amélie, Amélie"
console.log(name1 === name2);
// Expected output: false
console.log(name1.length === name2.length);
// Expected output: false

const name1NFC = name1.normalize("NFC");
const name2NFC = name2.normalize("NFC");

console.log(`${name1NFC}, ${name2NFC}`);
// Expected output: "Amélie, Amélie"
console.log(name1NFC === name2NFC);
// Expected output: true
console.log(name1NFC.length === name2NFC.length);
// Expected output: true

語法

js
normalize()
normalize(form)

引數

form 可選

"NFC""NFD""NFKC""NFKD" 中的一個,指定 Unicode 標準化形式。如果省略或為 undefined,則使用 "NFC"

這些值具有以下含義:

"NFC"

標準分解,然後是標準組合。

"NFD"

標準分解。

"NFKC"

相容性分解,然後是標準組合。

"NFKD"

相容性分解。

返回值

包含給定字串的 Unicode 標準化形式的字串。

異常

RangeError

如果 form 不是上述指定的值之一,則丟擲錯誤。

描述

Unicode 為每個字元分配一個唯一的數值,稱為程式碼點。例如,"A" 的程式碼點是 U+0041。然而,有時一個或多個程式碼點(或程式碼點序列)可以表示同一個抽象字元——例如,字元 "ñ" 可以表示為以下兩種方式之一:

  • 單個程式碼點 U+00F1。
  • "n" 的程式碼點 (U+006E) 後跟組合波浪線 (U+0303) 的程式碼點。
js
const string1 = "\u00F1";
const string2 = "\u006E\u0303";

console.log(string1); // ñ
console.log(string2); // ñ

但是,由於程式碼點不同,字串比較不會將它們視為相等。而且,每個版本中的程式碼點數量不同,它們的長度也不同。

js
const string1 = "\u00F1"; // ñ
const string2 = "\u006E\u0303"; // ñ

console.log(string1 === string2); // false
console.log(string1.length); // 1
console.log(string2.length); // 2

normalize() 方法透過將字串轉換為所有表示相同字元的程式碼點序列的通用標準化形式來幫助解決此問題。主要有兩種標準化形式,一種基於標準等效性,另一種基於相容性

標準等效性標準化

在 Unicode 中,如果兩個程式碼點序列代表相同的抽象字元,並且應始終具有相同的視覺外觀和行為(例如,它們應始終以相同的方式排序),則它們具有標準等效性。

您可以使用 normalize()"NFD""NFC" 引數來生成字串的一種形式,該形式對於所有標準等效的字串都是相同的。在下面的示例中,我們標準化了字元 "ñ" 的兩種表示形式:

js
let string1 = "\u00F1"; // ñ
let string2 = "\u006E\u0303"; // ñ

string1 = string1.normalize("NFD");
string2 = string2.normalize("NFD");

console.log(string1 === string2); // true
console.log(string1.length); // 2
console.log(string2.length); // 2

組合形式和分解形式

請注意,"NFD" 下標準化形式的長度為 2。這是因為 "NFD" 提供的是標準形式的分解版本,其中單個程式碼點被拆分為多個組合碼點。"ñ" 的分解標準形式是 "\u006E\u0303"

您可以指定 "NFC" 來獲得組合的標準形式,其中多個程式碼點在可能的情況下被替換為單個程式碼點。"ñ" 的組合標準形式是 "\u00F1"

js
let string1 = "\u00F1"; // ñ
let string2 = "\u006E\u0303"; // ñ

string1 = string1.normalize("NFC");
string2 = string2.normalize("NFC");

console.log(string1 === string2); // true
console.log(string1.length); // 1
console.log(string2.length); // 1
console.log(string2.codePointAt(0).toString(16)); // f1

相容性標準化

在 Unicode 中,如果兩個程式碼點序列代表相同的抽象字元,並且在某些(但不一定全部)應用程式中應視為相同,則它們是相容的。

所有標準等效的序列也都是相容的,但反之則不成立。

例如

  • 程式碼點 U+FB00 代表連字 "ff"。它與兩個連續的 U+0066 程式碼點 ("ff") 是相容的。
  • 程式碼點 U+24B9 代表符號 "Ⓓ"。它與 U+0044 程式碼點 ("D") 是相容的。

在某些方面(如排序)它們應被視為等效——而在某些方面(如視覺外觀)它們不應被視為等效,因此它們不具備標準等效性。

您可以使用 normalize()"NFKD""NFKC" 引數來生成字串的一種形式,該形式對於所有相容的字串都是相同的。

js
let string1 = "\uFB00";
let string2 = "\u0066\u0066";

console.log(string1); // ff
console.log(string2); // ff
console.log(string1 === string2); // false
console.log(string1.length); // 1
console.log(string2.length); // 2

string1 = string1.normalize("NFKD");
string2 = string2.normalize("NFKD");

console.log(string1); // ff <- visual appearance changed
console.log(string2); // ff
console.log(string1 === string2); // true
console.log(string1.length); // 2
console.log(string2.length); // 2

在應用相容性標準化時,考慮您打算如何使用這些字串很重要,因為標準化形式可能不適用於所有應用程式。在上面的示例中,標準化形式適用於搜尋,因為它允許使用者透過搜尋 "f" 來查詢字串。但它可能不適用於顯示,因為視覺表示不同。

與標準標準化一樣,您可以透過傳遞 "NFKD""NFKC" 來分別請求分解或組合的相容形式。

示例

使用 normalize()

js
// Initial string

// U+1E9B: LATIN SMALL LETTER LONG S WITH DOT ABOVE
// U+0323: COMBINING DOT BELOW
const str = "\u1E9B\u0323";

// Canonically-composed form (NFC)

// U+1E9B: LATIN SMALL LETTER LONG S WITH DOT ABOVE
// U+0323: COMBINING DOT BELOW
str.normalize("NFC"); // '\u1E9B\u0323'
str.normalize(); // same as above

// Canonically-decomposed form (NFD)

// U+017F: LATIN SMALL LETTER LONG S
// U+0323: COMBINING DOT BELOW
// U+0307: COMBINING DOT ABOVE
str.normalize("NFD"); // '\u017F\u0323\u0307'

// Compatibly-composed (NFKC)

// U+1E69: LATIN SMALL LETTER S WITH DOT BELOW AND DOT ABOVE
str.normalize("NFKC"); // '\u1E69'

// Compatibly-decomposed (NFKD)

// U+0073: LATIN SMALL LETTER S
// U+0323: COMBINING DOT BELOW
// U+0307: COMBINING DOT ABOVE
str.normalize("NFKD"); // '\u0073\u0323\u0307'

規範

規範
ECMAScript® 2026 語言規範
# sec-string.prototype.normalize

瀏覽器相容性

另見