来自javascript的charcode中的Unicode字符,用于charcodes> 0xFFFF

lee*_*mes 14 javascript unicode astral-plane

我需要从unicode charcode中获取字符串/ char,最后将其放入DOM TextNode中,以使用客户端JavaScript添加到HTML页面中.

目前,我正在做:

String.fromCharCode(parseInt(charcode, 16));
Run Code Online (Sandbox Code Playgroud)

其中charcode是包含charcode的十六进制字符串,例如"1D400".应该返回的unicode字符是, but a ?返回了!按预期返回16位范围(0000... FFFF)中的字符.

有任何解释和/或修改建议吗?

提前致谢!

Ano*_*mie 20

String.fromCharCode只能处理BMP中的代码点(即最多U + FFFF).为了处理更高的代码点,Mozilla Developer Network中的此函数可用于返回代理对表示:

function fixedFromCharCode (codePt) {
    if (codePt > 0xFFFF) {
        codePt -= 0x10000;
        return String.fromCharCode(0xD800 + (codePt >> 10), 0xDC00 + (codePt & 0x3FF));
    } else {
        return String.fromCharCode(codePt);
    }
}
Run Code Online (Sandbox Code Playgroud)


Tim*_*own 15

问题是JavaScript中的字符(大部分)是UCS-2编码的,但可以在JavaScript中将基本多语言平面之外的字符表示为UTF-16代理对.

以下函数适用于将带有破折号字符的punycode转换为Unicode:

function utf16Encode(input) {
    var output = [], i = 0, len = input.length, value;
    while (i < len) {
        value = input[i++];
        if ( (value & 0xF800) === 0xD800 ) {
            throw new RangeError("UTF-16(encode): Illegal UTF-16 value");
        }
        if (value > 0xFFFF) {
            value -= 0x10000;
            output.push(String.fromCharCode(((value >>>10) & 0x3FF) | 0xD800));
            value = 0xDC00 | (value & 0x3FF);
        }
        output.push(String.fromCharCode(value));
    }
    return output.join("");
}

alert( utf16Encode([0x1D400]) );
Run Code Online (Sandbox Code Playgroud)


Mik*_*uel 9

EcmaScript语言规范的第8.4节说

当String包含实际文本数据时,每个元素都被视为单个UTF-16代码单元.无论这是否是String的实际存储格式,String中的字符都按其初始代码单元元素位置编号,就像它们使用UTF-16表示一样.对字符串的所有操作(除非另有说明)将它们视为未分化的16位无符号整数的序列; 它们不能确保生成的String是标准化形式,也不能确保语言敏感的结果.

因此,您需要将补充代码点编码为UTF-16代码单元对.

文章"Java平台中的补充字符"很好地描述了如何执行此操作.

UTF-16使用一个或两个无符号16位代码单元的序列来编码Unicode代码点.值U + 0000到U + FFFF以一个16位单位编码,具有相同的值.补充字符以两个代码单元编码,第一个来自高代理范围(U + D800到U + DBFF),第二个来自低代理范围(U + DC00到U + DFFF).这在概念上似乎与多字节编码类似,但有一个重要的区别:值U + D800到U + DFFF保留用于UTF-16; 没有字符作为代码点分配给它们.这意味着,软件可以在字符串中为每个单独的代码单元分辨它是代表一个单元字符,还是它是两个单元字符的第一个或第二个单元.这是对一些传统的多字节字符编码的重大改进,其中字节值0x41可以表示字母"A"或者是双字节字符的第二个字节.

下表显示了几个字符的不同表示形式:

代码点/ UTF-16代码单元

U + 0041/0041

U + 00DF/00DF

U + 6771/6771

U + 10400/D801 DC00

一旦知道了UTF-16代码单元,就可以使用javascript函数创建一个字符串String.fromCharCode:

String.fromCharCode(0xd801, 0xdc00) === ''
Run Code Online (Sandbox Code Playgroud)

  • +1引用语言规范. (2认同)