JavaScript的Unicode难题

退一步说, JavaScript处理Unicode时有些怪异. 这篇文章会说明JS在Unicode上令人痛苦的部分, 然后提供解决方案, 并说明在未来的ECMAScript6中是如何改善这些问题的.

Unicode基础知识
       为了您能更好的理解Unicode在JavaScript里的问题, 先确保大家了解Unicode为何物.
       最简单的我们可以把 Unicode 想像成一个数据库, 任何您能想到的符号都对应着一个数字(我们把这个数字叫做它的码位)和一个唯一的名字. 这样一来, 我们可以方便的引用一个符号, 而不必直接使用这个符号本身.

例如:

码位通常用16进制数字表示, 用0补位, 至少4位数加上 U+ 前缀.

码们的范围是从U+0000至U+10FFFF. 可以表示110万个以上的符号.为了良好的组织如此庞大的数据, Unicode把这些码们分成了17个平面, 大约每个平面包含了6.5万个码位.

第一部分也是最重要的部分叫做基本多文种平面或BMP, 这部分包含了我们通常会用到的符号. 在英文文本文档中通常来说您只需要使用BMP就足够了.

BMP之外还剩下100万个可用码位..包含这100万个码位的平面叫做补充平面或星际平面.

星际平面十分容易辨识: 当您需要使用大于4位的16进制数来表示码位时, 这个码位就是星际码位.

现在我们已经了解了Unicode基础知道, 下面来看看它是如何应用到JavaScript的字符串里的.

转义序列

您之前可能见过下面这些东西:

  1. >> ‘\x41\x42\x43‘
  2. ‘ABC‘
  3. >> ‘\x61\x62\x63‘
  4. ‘abc‘

这些叫做16进制转义序列. 它们包含2位16进制数字表示码位. 比如, ‘\x41‘ 表示 U+0041 LATIN CAPITAL LETTER A. 细心的读者可能发现了, 这些转义序列可以表示U+0000至U+00FF的码位.

还有一种常见的转义:

  1. >> ‘\u0041\u0042\u0043‘
  2. ‘ABC‘
  3. >> ‘I \u2661 JavaScript!‘
  4. ‘I ? JavaScript!‘

这些叫做Unicode转义序列. 它们使用4位16进制数表示一个码位. 比如: ‘\u2661‘ 表示 U+2661 WHITE HEART SUIT. 这些转义序列表示的范围是U+0000至U+FFFF, 包含了全部的BMP.

那么对于其它平面呢? 比如星际平面? 我们需要4位以上的16进制数才能表示它们的码位... 如何来转义??
        在 ECMAScript 6 里, 这个很简单, 因为添加了一种新的转义方式: Unicode码位转义.
例如:

  1. >> ‘\u{41}\u{42}\u{43}‘
  2. ‘ABC‘

  1. >> ‘\u{1F4A9}‘
  2. ‘?‘ // U+1F4A9 PILE OF POO

为了向后兼容ECMAScript5和更早的环境, 一个不好的方案就是使用替代组合:

  1. >> ‘\uD83D\uDCA9‘

  1. ‘?‘ // U+1F4A9 PILE OF POO

由两者组成一个星际符号. 要注意的是这两个组成部分已经失去了它们本身的码位意义.

使用这种替代组合后, 所有的星际码位都可以被表示了.. 大家应该已经感觉到了, 单个码位可以表示的BMP与需要替代组合才能表示的星际符号混在一起, 令人困惑, 甚至会造成讨厌的后果.

在JavaScript里计算字符数
       如果你想计算字符串的长度你会怎么做?
       我首先想到的是用 length 属性.

  1. >> ‘A‘.length // U+0041 LATIN CAPITAL LETTER A
  2. 1
  3. >> ‘A‘ == ‘\u0041‘
  4. true
  5. >> ‘B‘.length // U+0042 LATIN CAPITAL LETTER B
  6. 1
  7. >> ‘B‘ == ‘\u0042‘
  8. true

上面的例子里, length 属性确实表示了字符的数量. (这说得通, 因为如果我们使用转义序列来表示这个字符, 只需要一个转义就可以(\u0041 表示 A)).

来看一个不一样的例子:

  1. >> ‘?‘.length // U+1D400 MATHEMATICAL BOLD CAPITAL A
  2. 2
  3. >> ‘?‘ == ‘\uD835\uDC00‘
  4. true
  5. >> ‘?‘.length // U+1D401 MATHEMATICAL BOLD CAPITAL B
  6. 2
  7. >> ‘?‘ == ‘\uD835\uDC01‘
  8. true
  9. >> ‘?‘.length // U+1F4A9 PILE OF POO
  10. 2
  11. >> ‘?‘ == ‘\uD83D\uDCA9‘
  12. true

在JavaScript内部, 使用上文提到的替代组合来表示星际字符, 并且暴露出组成替代组合的2个字符. 如果你使用ECMAScript 5兼容的转义序列来表示符号, 就需要2个转义字符来表示一个星际符号. 这令人困惑, 因为人们通常是以一个Unicode符号或字母的一个整体来考虑它们, 而不是把一个星际字符想成2部分.

时间: 2024-08-29 19:19:44

JavaScript的Unicode难题的相关文章

#翻译# 深入JavaScript的Unicode难题(上)

position:static(静态定位) 当position属性定义为static时,可以将元素定义为静态位置,所谓静态位置就是各个元素在HTML文档流中应有的位置 podisition定位问题.所以当没有定义position属性时,并不说明该元素没有自己的位置,它会遵循默认显示为静态位置,在静态定位状态下无法通过坐标值(top,left,right,bottom)来改变它的位置. position:absolute(绝对定位) 当position属性定义为absolute时,元素会脱离文档流

javascript实现unicode与字符互相转换

javascript实现unicode与字符互相转换. <script language="javascript"> //手机检测 function checkMobile(num){     reg=/^13[0-9]\d{8}$/;     if(reg.test(num)){         return true;     }else{         reg=/^15[8-9]\d{8}$/;         if(reg.test(num)){         

JavaScript字符集--------Unicode转义序列

Unicode是ASCII和Latin-1的超集. JavaScript程序都是用Unicode字符集编写而成的,但在一些计算机硬件和软件里根本无法显示或者输入Unicode字符全集,为了解决这一现象JavaScript定义了一种特殊序列,这种序列使用6个ASCII字符来代表任意16位Unicode内码,这种特殊序列统称为Unicode转义序列,它均以\u为前缀,其后跟随4个十六进制数, 比如: "café"==="caf\u00e9" // =>true 但

javaScript 实现Unicode字符转换以及汉字转拼音

一.JavaScript实现汉字转为Unicode 1.通过解编码的方式转换 /* *js Unicode编码转换 */  var decToHex = function(str) {     var res=[];     for(var i=0;i < str.length;i++)         res[i]=("00"+str.charCodeAt(i).toString(16)).slice(-4);     return "\\u"+res.jo

JavaScript为unicode编码转换为中文

代码laycode - v1.1 关于这样的数据转换为中文问题,常用的以下方法. 1. eval解析或new Function("'+ str +'")()  str = eval("'" + str + "'"); // "我是unicode编码" 1 代码laycode - v1.1 2. unescape 解析  str = unescape(str.replace(/\u/g, "%u")); //

JavaScript为unicode编码转换为中文(转)

var str = "\\u6211\\u662Funicode\\u7F16\\u7801"; 关于这样的数据转换为中文问题,常用的以下方法. 1. eval解析或new Function("'+ str +'")() str = eval("'" + str + "'"); // "我是unicode编码" 2. unescape 解析 str = unescape(str.replace(/\u/g,

【译】每个JavaScript开发者都该懂的Unicode

本文是我(兔子)在众成翻译上认领并翻译的:每个JavaScript开发者都该懂的Unicode (译者注:本文含有Unicode辅助平面的特殊字符,部分浏览器可能无法正确显示,但并不影响理解文章内容.) 在动笔写这篇文章之前,我得先忏悔一下:在很长一段时间里我对Unicode充满了恐惧. 每次遇到需要Unicode知识的编程问题时,我总是找一个hack方案来解决,但解决方案的原理我也不懂. 直到遇见一个需要深入了解Unicode知识才能解决的问题,我才停止了这种逃避.因为这个问题没办法应用特定情

Unicode in JavaScript

Unicode in JavaScript by Jinya [转载请注明出处,http://blog.csdn.net/EI__Nino] 名词解释: BMP:(BasicMultilingual Plane)它又简称为"零号平面", plane 0 UCS:通用字符集(Universal Character Set, UCS) ISO:国际标准化组织(ISO) UTF:UCS Transformation Format, BOM:Byte Order Mark 字节序 CJK: 统

unicode 编码在线转换工具--javascript

unicode 编码在线转换工具--javascript 本人在网上搜索,看到有使用javascript做unicode编码转换的,感觉很好玩,所以拿来使用的. 这个功能有目前测试了两种: 1)unicode互相转换,例如\u4e2d\u56fd转换成字符,支持中文和英文: 2)URL编码的解析,例如众所周知的%20是表示空格,还有%24,%33,%44,%62等等: 我相信,只要你试试上面的字符进行解码,你就会知道他们之间关系,如何表示字符,数字,字母. 以上可以直接运行.下面给出相关的JS代