BMP之外的JavaScript字符串

Del*_*ani 38 javascript unicode utf-16 surrogate-pairs astral-plane

BMP是基本的多语言平面

根据JavaScript:好的部分:

JavaScript是在16位字符集的时候构建的,因此JavaScript中的所有字符都是16位宽.

这让我相信JavaScript使用UCS-2(不是UTF-16!)并且只能处理U + FFFF以前的字符.

进一步调查证实了这一点:

> String.fromCharCode(0x20001);
Run Code Online (Sandbox Code Playgroud)

fromCharCode返回Unicode字符时,该方法似乎只使用最低16位.试图获得U + 20001(CJK统一表意文字20001)而不是返回U + 0001.

问题:是否可以在JavaScript中处理后BMP字符?


2011-07-31:来自Unicode支持Shootout的 12个幻灯片:好的,坏的,以及(大部分)Ugly很好地解决了与此相关的问题:

bob*_*nce 34

取决于"支持"的含义.您当然可以使用代理项将非UCS-2字符放入JS字符串中,如果可以,浏览器将显示它们.

但是,JS字符串中的每个项目都是一个单独的UTF-16代码单元.没有处理全字符的语言层面的支持:所有标准字符串成员(length,split,slice等)都处理代码单元没有字符,所以会很愉快地拆分代理对或持有无效的替代序列.

如果你想要代理意识的方法,我担心你必须自己开始写它们!例如:

String.prototype.getCodePointLength= function() {
    return this.length-this.split(/[\uD800-\uDBFF][\uDC00-\uDFFF]/g).length+1;
};

String.fromCodePoint= function() {
    var chars= Array.prototype.slice.call(arguments);
    for (var i= chars.length; i-->0;) {
        var n = chars[i]-0x10000;
        if (n>=0)
            chars.splice(i, 1, 0xD800+(n>>10), 0xDC00+(n&0x3FF));
    }
    return String.fromCharCode.apply(null, chars);
};
Run Code Online (Sandbox Code Playgroud)

  • @Mathias:JavaScript是UTF-16无知的.它为您提供了一系列16位代码单元,并允许您将所需内容放入其中.如果需要,您可以在其中存储代理,但是您不会获得任何特殊功能来将它们作为字符处理.是否要将其描述为"使用"UCS-2或UTF-16是一个语义参数,没有一个明确的答案.然而,无论JS中的语言级支持如何,浏览器的其他部分都支持在UI中呈现/交互的代理,因此将它们包含在JS字符串中是有意义的. (3认同)
  • @bobince谢谢!我进一步调查了一下,并在此处写了我的发现:http://mathiasbynens.be/notes/javascript-encoding反馈欢迎. (3认同)
  • (更新fromCodePoint以匹配为ECMAScript 6提供的正确Unicode支持的名称.现在这实际上是一个polyfill.) (2认同)