String.prototype.toWellFormed()

Baseline 2023

Newly available

Since October 2023, this feature works across the latest devices and browser versions. This feature might not work in older devices or browsers.

StringtoWellFormed() 方法返回一个字符串,其中该字符串的所有单独代理项都被替换为 Unicode 替换字符 U+FFFD。

语法

js
toWellFormed()

返回值

新的字符串是原字符串的一个拷贝,其中所有的单独代理项被替换为 Unicode 替换字符 U+FFFD。如果 str 是格式正确的,仍然会返回一个新字符串(本质上是 str 的一个拷贝)。

描述

JavaScript 中的字符串是 UTF-16 编码的。UTF-16 编码中有代理对的概念,这一概念在 UTF-16 字符、Unicode 码位和字素簇部分有详细介绍。

toWellFormed() 迭代字符串的码元,并将任何单独代理项替换为 Unicode 替换字符 U+FFFD 。这确保了返回的字符串格式正确并可用于期望正确格式字符串的函数,比如 encodeURI。由于引擎能够直接访问字符串的内部表示,与自定义实现相比 toWellFormed() 更高效。

当在某些上下文中使用格式不正确的字符串时,例如 TextEncoder,它们会自动转换为使用相同替换字符的格式正确的字符串。当单独代理项被呈现时,它们也会呈现为替换字符(一个带有问号的钻石形状)。

示例

使用 toWellFormed()

js
const strings = [
  // 单独的前导代理
  "ab\uD800",
  "ab\uD800c",
  // 单独的后尾代理
  "\uDFFFab",
  "c\uDFFFab",
  // 格式正确
  "abc",
  "ab\uD83D\uDE04c",
];

for (const str of strings) {
  console.log(str.toWellFormed());
}
// Logs:
// "ab�"
// "ab�c"
// "�ab"
// "c�ab"
// "abc"
// "ab😄c"

避免 encodeURI() 错误

如果传递的字符串格式不正确, encodeURI 会抛出错误。可以先通过使用 toWellFormed() 将字符串转换为格式正确的字符串来避免这种情况。

js
const illFormed = "https://example.com/search?q=\uD800";

try {
  encodeURI(illFormed);
} catch (e) {
  console.log(e); // URIError: URI malformed
}

console.log(encodeURI(illFormed.toWellFormed())); // "https://example.com/search?q=%EF%BF%BD"

规范

Specification
ECMAScript Language Specification
# sec-string.prototype.towellformed

浏览器兼容性

BCD tables only load in the browser

参见