为什么JSON编码使用UTF-16代理对而不是直接使用Unicode代码点?

7
为了转义不在基本多语种平面内的代码点,该字符使用UTF-16代理对进行编码,表示为一个十二个字符的序列。例如,只包含G谱号字符(U+1D11E)的字符串可以表示为"\uD834\uDD1E"
ECMA-404:JSON数据交换格式 我认为根本无需对此字符进行编码,因此它可以直接表示为""。但是,如果需要对其进行编码,则必须按照规范进行编码,例如"\uD834\uDD1E",而不能像合理的方式一样编码为"\u1d11e"。这是为什么呢?

3
为了历史原因,对不起,我是想说“出于历史原因”:-) 是的,您可以选择直接使用Unicode代码点或使用编码的代理对。 - gnasher729
3
\u 转义格式仅限于4个十六进制数字,因此只能编码16位值。 0x1D11E不适合16位,因此需要使用代理对。这追溯到UCS-2时代,当时所有Unicode代码点都可以很好地适应16位。当Unicode超过16位时,发明了UTF-16以突破编码限制,但仍需要向后兼容现有的UCS-2数据和格式。 - Remy Lebeau
4
如果支持 "\u1d11e" 表示 "",那么使用 \u1d11 代表 来编码字符串 "ᴑe" 就会变得困难。一个更好的问题是,为什么语言中还没有添加像 Python 和 C++ 中一样支持类似 "\U0001d11e" 这样的序列的功能。 - 一二三
1
ECMAScript 6 添加了\u{1d11e}语法(类似于Perl)。 - nwellnhof
3
ECMAScript 6 - 虽然语法简洁,但 JSON 已经被广泛实现,引入新的语法需要升级所有解析器,这不值得麻烦。 - Beni Cherniavsky-Paskin
1个回答

10

JSON的一个关键架构特性是,JSON编码的对象是有效的Javascript字面量,可以使用eval函数进行评估。然而,不幸的是,旧的Javascript实现仅支持在字符串字面量中使用四个十六进制字符的16位Unicode转义序列,因此在可移植的方式中使用UTF-16代理对的转义序列是唯一的方法来处理大于0xFFFF的码位。(允许使用任意码位的\u{...}语法只在ECMAScript 6中引入.)

但正如你所提到的,如果您的应用程序支持Unicode JSON文本,则无需使用转义序列。只需直接以相应的Unicode格式对字符进行编码即可。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接