Effective JavaScript String Encoding Item 7
来源:互联网 发布:java httpclient api 编辑:程序博客网 时间:2024/04/27 17:45
本系列作为Effective JavaScript的读书笔记。
提起Unicode,也许许多程序员都会觉得这玩意很麻烦,可是本质上,Unicode并不复杂。世界上每种语言的每一个文字都被一个整形数值表示,范围是0到1114111,这个值在Unicode术语中被称为Code Point。在字符到整形数值的映射上,Unicode和其它编码方式诸如ASCII并没有区别。
但是,Unicode存在多种编码方式,而ASCII只有一种方式:
字符集
编码方式
ASCII
ASCII Encoding, e.g. A -> 65
Unicode
UTF-8, UTF-16, UTF-32, etc
那么为什么Unicode有这么多种编码方式呢?因为在不同情况下对操作的时间和空间要求是不一样的。
而在设计之初,Unicode估计所有的Code Points能够被2的16次方,也就是65536来表示。这种编码方式就是UCS-2,它是最初的对于Unicode的16位编码方式。通过这种方式,每一个Code Point都可以用一个16位的值进行表示,该表示被称为Code Unit。这种表示方式的优点在于,对Unicode字符串的索引操作都可以在常数时间内完成,因为所有的字符都是由16位,也就是2个比特表示。
因为这种编码方式的便利性,所以一些平台诸如Java,JavaScript都采用了它。因此,JavaScript的字符串每一个字符都是由2个比特表示的。
而随着Unicode字符集的扩展,65536已经满足不了需求了,目前Unicode字符集中字符的数量已经超过了2的20次方。因此,新增加的部分被组织到由17个2的16次方所组成的子范围内。(17 * 2^16 = 1114112,所以目前Unicode的Code Point范围是0-1114111)
第一个子范围,用来容纳原来UCS-2中的字符集,它也被称为Basic Multilingual Plane(BMP)。剩下的16个子范围,被称为Supplementary Planes。
为了表示更多的字符,UCS-2的继任者UTF-16,是这样设计的:
对于Code Point大于等于65536的字符,由一对16位的Code Unit表示。对于Code Point小于65536的字符,还是只需要1个16位的Code Unit表示。因此,UTF-16是一种变长编码方式,所以在对Code Point做indexing操作也不是常数时间了。它通常都需要从字符串的开始往后搜索。
对于JavaScript,字符串的length属性,charAt以及charCodeAt方法,都是在Code Unit的基础上工作,而不是Code Point。因此,当JavaScript需要表示出于Supplementary Plane中的Code Point时,它都会使用两个CodeUnit来表示,简而言之:
JavaScript字符串是由16位的Code Unit组成的。
所以,当需要处理BMP以外的Code Point时,会带来一些问题,因为你不能依赖于length属性,charAt以及charCodeAt方法了。这时候可以考虑使用一些成熟的第三方库。
总结:
- JavaScript的字符串由16比特的Code Unit组成,而不是由Unicode Code Point组成。
- 大于等于65536的Code Point在JavaScript中由两个Code Units组成,被称为Surrogate Pair。
- Surrogate Pair会影响到length,charAt,charCodeAt以及正则表达式中 . 的工作方式。
- 处理Code Point超过65535的字符串时,考虑使用第三方的库并查阅它的文档。
- Effective JavaScript String Encoding Item 7
- Effective JavaScript Basics Item 1-6
- Effective JavaScript Item 10 避免使用with
- Effective JavaScript Item 11 掌握闭包
- Effective JavaScript Item 12 理解Variable Hoisting
- Effective JavaScript Variable Scope Item 8-9 Globals and Locals
- Effective JavaScript Item 23 永远不要修改arguments对象
- Effective JavaScript Item 28 不要依赖函数的toString方法
- Effective JavaScript Item 31 优先使用Object.getPrototypeOf,而不是__proto__
- Effective JavaScript Item 32 绝不要修改__proto__
- Effective JavaScript Item 34 在prototype上保存方法
- Effective JavaScript Item 35 使用闭包来保存私有数据
- Effective JavaScript Item 37 认识this的隐式指向
- Effective JavaScript Item 40 避免继承标准类型
- Effective JavaScript Item 61 不要阻塞事件队列
- Effective JavaScript Item 54 将undefined视为"没有值"
- Effective JavaScript Item 55 接受配置对象作为函数参数
- Effective Java: Item 1
- Git 常用命令速查表
- 阿里云CentOS 系统数据盘挂载
- Ubuntu下grub启动引导修改
- 算法导论第8章—线性时间排序
- PHP+MYSQL实现全文检索及全文检索工具
- Effective JavaScript String Encoding Item 7
- Oracle JOB 错误ora-12012
- ACM 146. [USACO Jan08] 贝茜的晨练计划(dp)
- lua简单操作sqlite3
- c#转义字符总结
- 1
- 哈夫曼树
- 【大宝的犀牛】飞利浦RQ370剃须刀建模教程
- 查询oracle srid 对应的EPSG代码