String.fromCharCode() 与 String.fromCodePoint() 的区别是什么
在 javascript 中,将 unicode 码点转换为字符串主要使用 string.fromcharcode() 和 string.fromcodepoint()。前者是静态方法,仅支持 bmp(基本多文种平面)内的字符,超出范围会返回代理对或乱码;后者支持所有 unicode 码点,包括辅助平面字符,是现代开发的首选。

这两个方法的核心区别在于处理范围。BMP 包含前 65,536 个字符,对应码点 U+0000 到 U+FFFF。fromCharCode 直接将这些数值作为 UTF-16 代码单元处理。如果传入大于 0xFFFF 的值,它会截断高位或产生非预期的代理对。而 fromCodePoint 能够识别并生成正确的 UTF-16 代理对序列,从而表示如 emoji 或罕见汉字等辅助平面字符。
console.log(String.fromCharCode(0x1F600)); // 输出: "?" (两个独立的代理对字符,显示为乱码或占位符) console.log(String.fromCodePoint(0x1F600)); // 输出: "?" (正确的 Emoji)
预期结果:
第一行输出两个独立的代理对字符,通常在现代浏览器中显示为两个方块或问号。
第二行输出正确的笑脸 Emoji。
如何将字符串编码转换回 Unicode 码点数组
要将字符串转换回 Unicode 码点数组,可以使用展开运算符 [...str] 结合 .charCodeAt() 或 .codePointAt()。对于包含代理对的字符串,必须使用 codePointAt() 才能正确获取完整的码点值,否则只能得到高代理项或低代理项的独立数值。

展开运算符 [...str] 会自动遍历字符串中的完整字符,包括由两个 UTF-16 代码单元组成的代理对。这意味着迭代器每次返回一个完整的字符。接着,对该字符调用 codePointAt(0) 即可获取其完整的 Unicode 码点。如果使用 charCodeAt(0),它只返回第一个代码单元的数值,对于辅助平面字符,这会丢失信息。
const str = "?A"; const codePoints = [...str].map(char => char.codePointAt(0)); console.log(codePoints); // 输出: [128512, 65] // 对比 charCodeAt const wrongWay = [...str].map(char => char.charCodeAt(0)); console.log(wrongWay); // 输出: [55357, 56832, 65] (错误地拆分了 Emoji)
预期结果:
第一行输出数组 [128512, 65],其中 128512 是 ? 的码点,65 是 A 的码点。
第二行输出数组 [55357, 56832, 65],其中 55357 是高代理项,56832 是低代理项,65 是 A 的码点。
当输入包含非法 UTF-16 序列时如何处理
当输入字符串包含孤立的代理项(即未配对的 high surrogate 或 low surrogate)时,String.fromCodePoint() 会抛出 RangeError。这是因为单独的代理项不是有效的 Unicode 标量值。为了安全处理,需要在调用前验证码点或使用 try-catch 块捕获异常。

UTF-16 编码规定,辅助平面字符必须由一对代理项组成:高代理项范围 U+D800–U+DBFF,低代理项范围 U+DC00–U+DFFF。如果尝试将一个孤立的高代理项或低代理项作为码点传递给 fromCodePoint,引擎会检测到这是无效的 Unicode 标量值并抛出错误。在实际应用中,这通常发生在解析损坏的数据或手动构造字符串时。
try {
// 尝试创建一个孤立的高代理项
const invalid = String.fromCodePoint(0xD800);
console.log(invalid);
} catch (e) {
console.error(e.message); // 输出: "Invalid code point"
}
// 正确的做法:配对代理项
const valid = String.fromCodePoint(0x1F600);
console.log(valid); // 输出: "?"
预期结果:
第一块代码抛出异常,控制台打印 "Invalid code point"。
第二块代码正常输出 "?"。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











