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

浏览器兼容性

另见