ECMAScript 2019 中的 String.fromCharCode 和 String.fromCodePoint:UTF-16 的坑

阅读时长 4 分钟读完

在前端开发中, String 类型的实例是我们经常使用的,因为字符串可以表示页面上的文字以及从服务端传递的数据。在 ECMAScript 2019(ES10)中, String 类型新增了两个方法: String.fromCharCode 和 String.fromCodePoint,它们可以让我们更方便地进行字符编码与解码。然而,这两个方法却存在一个潜在的坑,本文将为大家详细介绍其中的细节。

String.fromCharCode

String.fromCharCode 方法接受一系列的数字参数,每个参数表示一个 UTF-16 编码的字符,返回值是由这些字符拼接成的字符串。让我们来看一个例子:

上述例子中,我们使用了三个数字参数分别代表字符 A、B、C 的 UTF-16 编码值,将其传入 fromCharCode 方法中,返回了一个由这三个字符组成的字符串。

然而,String.fromCharCode 只能表示 UTF-16 编码中 Unicode 编号范围在第一个 BMP 平面(编号为 U+0000 至 U+FFFF)之间的字符。如果传入的参数中包含了 BMP 平面之外的字符,String.fromCharCode 将不会成功创建对应的字符串。让我们用一个例子来说明这个问题:

以上例子中,我们尝试使用 String.fromCharCode 方法来创建一个字符,它的 Unicode 编号是 0x2F804,不幸的是,这个编码属于第二个 BMP 平面,也就是不在 UTF-16 编码范围内的。所以,fromCharCode 方法调用后返回了字符串 "undefined",这显然不是我们想要的结果。

String.fromCodePoint

因为 String.fromCharCode 无法表示 BMP 平面之外的字符,所以 ECMAScript 2015(ES6)中引入了 String.fromCodePoint 方法来弥补其不足。与 fromCharCode 不同的是,fromCodePoint 方法可以解析传入的参数中除 BMP 平面之外的字符,然后生成对应的字符串。让我们看一个例子:

上述例子中,我们使用了 fromCodePoint 方法来生成一个字符,它的 Unicode 编号是 0x2F804,这个编码属于第二个 BMP 平面之外,然而,fromCodePoint 方法却返回了我们期望的字符串 "你"。

但是,String.fromCodePoint 同样存在其特殊之处。当传入参数为浮点数、负数、NaN、Infinity、大于 0x10FFFF 等不合法参数时,它将抛出 RangeError 异常。同时,当传入的参数存在小数部分时,fromCodePoint 方法会向下取整到最近的整数后再进行字符生成,例如:

上述例子中,我们尝试传入两个浮点数 97.5 和 98.5,注意这意味着传入 fromCodePoint 的参数实际上是数值 97 和 98。fromCodePoint 方法会将这两个数值转为其对应的字符,生成字符串 "ab"。

总结与建议

在使用 String.fromCharCode 与 String.fromCodePoint 时,我们需要注意以下几点:

  1. String.fromCharCode 只能表示 BMP 平面以内的字符,如果需要表示 BMP 平面之外的字符,建议使用 String.fromCodePoint 方法。
  2. String.fromCharCode 在接受参数时要求参数必须满足 UTF-16 编码的规范,如果不确定参数类型是否正确,建议先将其转为十六进制整数格式。
  3. String.fromCodePoint 在接受参数时要求参数必须为整数,且范围在 U+0000 至 U+10FFFF 之间。如果传入的参数存在小数部分或超出了这个范围,fromCodePoint 方法可能抛出 RangeError 异常。
  4. 在实际开发中,如果需要使用一些特殊字符,例如 Emoji 表情、各类语言的字符等,应该先确定其对应的 Unicode 编码值,再根据需要选择合适的方法(如 escape、encodeURI)进行字符编码。

以上是本文对 String.fromCharCode 与 String.fromCodePoint 方法的介绍,希望能够对大家在实际开发中使用这些方法时有所帮助。

来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/64a1223148841e9894d6778f

纠错
反馈