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

时间:2011-03-27 01:03:01

标签: javascript unicode astral-plane

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

目前,我正在做:

String.fromCharCode(parseInt(charcode, 16));

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

任何有关更正的解释和/或建议?

提前致谢!

4 个答案:

答案 0 :(得分: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);
    }
}

答案 1 :(得分:15)

问题是JavaScript中的字符是(mostly) UCS-2 encoded,但可以在JavaScript中将基本多语言平面之外的字符表示为UTF-16代理项对。

以下功能改编自Converting punycode with dash character to 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]) );

答案 2 :(得分:9)

EcmaScript语言规范的第8.4节说

  

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

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

文章"Supplementary Characters in the Java Platform"很好地描述了如何做到这一点。

  

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) === ''

答案 3 :(得分:0)

String.fromCodePoint()似乎也可以解决问题。参见here

console.log(String.fromCodePoint(0x1D622, 0x1D623, 0x1D624, 0x1D400));

输出: