在 ECMAScript 6 之前,JavaScript 对每个字符都是按照 16 位编码的(UTF-16)处理的。即默认每个字符在计算机底层都是由 16 个 0 和 1 的序列组成。 一个这样的 16 位序列称一个 编码单元(code unit)

像字符串的 length 属性和 charAt() 方法都是基于 16 位编码单元进行处理的。

但随着 Unicode 字符集 的不断扩展,0x0000~0xFFFF 这个区间范围,不足以表示所有字符了。这时再使用字符串的 length 属性和 charAt() 方法就存在问题了。

码点

  1. 码点(Code Points)就是字符编码,用一个数字表示一个字符。
  2. 码点既能表示 0x0000~0xFFFF 范围的字符,也能表示 > 0xFFFF 范围之外的字符。
  3. 码点在计算机底层由 1 个或 2 个编码单元组成。

BMP

0x0000~0xFFFF 区间范围,称为 Basic Multilingual Plane (BMP)。在 BMP 中(包括),一个字符唯一对应一个编码单元(一个 16 位二进制序列)。

BMP 之外的区间称为 supplementary planes。在 supplementary planes 中的每个字符,由 2 个编码单元组成,称 代理对(surrogate pairs)

  1. 0x0000~0xFFFF 区间范围,一个码点等于一个编码单元。
  2. > 0xFFFF 区间范围,一个码点等于两个编码单元。

老方法的问题

在 ECMAScript 5 中,每个字符都被看做,由一个编码单元组成。那么,在处理 supplementary planes 中的字符时,就有问题了。

var text = "?";console.log(text.length);           // 2
console.log(/^.$/.test(text));      // false
console.log(text.charAt(0));        // ""
console.log(text.charAt(1));        // ""
console.log(text.charCodeAt(0));    // 55362
console.log(text.charCodeAt(1));    // 57271
复制代码

"?" 在计算机底层由两个编码单元组成,也就是由两个 16 位编码序列组成。而在 .length 属性、charAt() 方法和 charCodeAt() 方法的世界观里,每个字符都是用一个 16 位编码序列表示的。

所以,.length 属性值是 2;charAt(0)charAt(1) 其实取的是 "?" 这个字第一个编码单元和第二个编码单元所表示的字符;charCodeAt(0) 更不能取到正确的字符了。

本质上,charAtcharCodeAt 后面的数字是表示编码单元的索引值。

从 charCode 到 codePoint

上面的例子里,如果使用 codePointAt(),就不存在问题了。

var text = "?a";console.log(text.charCodeAt(0));    // 55362
console.log(text.charCodeAt(1));    // 57271
console.log(text.charCodeAt(2));    // 97console.log(text.codePointAt(0));   // 134071
console.log(text.codePointAt(1));   // 57271
console.log(text.codePointAt(2));   // 97
复制代码

> 0xFFFF 区间范围,字符编码值(char code) 不再有效,码点依旧有效。所以,我们要:

  • String.fromCharCode 迁移到 String.fromCodePoint
  • string.charCodeAt 迁移到 string.codePointAt

工具方法:is32Bit

我们可以写一个工具方法,判断一个字符是不是 BMP 之外的字符。

function is32Bit(c) {return c.codePointAt(0) > 0xFFFF;
}console.log(is32Bit("?"));         // true
console.log(is32Bit("a"));          // false
复制代码

扩展连接

  1. Universal Character Set characters, from wikipedia.org
  2. Character Code Charts, from unicode.org

参考链接

  • Better Unicode Support, from "Understanding ES6"

(完)

ECMAScript 6:更好的 Unicode 支持相关推荐

  1. wxWidgets:wxWidgets 中的 Unicode 支持

    wxWidgets:wxWidgets 中的 Unicode 支持 wxWidgets:wxWidgets 中的 Unicode 支持 什么是统一码? Unicode 表示法和术语 wxWidgets ...

  2. 将dataset中的数据导出至Excel中而不需要安装MS Excel的方法(含UNICODE支持)

    偶尔做界面程序,需要一个导出Excel,而在客户端又不用安装MS Excel的方法,总结如下. 测试了两种方法,第一种方法如下(此方法支持UNICODE不存在问题): 参考:http://www.sw ...

  3. Qt 5.14 稳定版发布,带来更好的 HiDPI 支持和改进 3D 模块

    计划于上个月发布的 Qt 5.14 经过短暂的推迟后,现在终于发布了稳定版.该版本以及明年的 Qt 5.15 LTS 开始为发布 Qt 6 做铺垫.开发团队表示,尽管他们正在努力通过标记不推荐使用的功 ...

  4. C++11 Unicode 支持

    1. char16_t 与 char32_t 在 C++98 中,为了支持 Unicode 字符,使用 wchar_t 类型来表示"宽字符",但并没有严格规定位宽,而是让 wcha ...

  5. mc服务器物品给予,[管理|功能]GiveItem —— 给予物品 | 更好的Give|支持NBT|保存物品[1.12.2|1.16.X]...

    您尚未登录,立即登录享受更好的浏览体验! 您需要 登录 才可以下载或查看,没有帐号?注册(register) x 本帖最后由 AeXiaohu 于 2021-7-10 14:29 编辑 大家用的什么来 ...

  6. linux mate桌面管理器,Ubuntu MATE 18.04 LTS采用新的桌面布局,更好的HiDPI支持

    Ubuntu MATE 18.04 LTS作为昨天Ubuntu 18.04 LTS(Bionic Beaver)操作系统系列的一部分发布,作为轻量级MATE桌面环境的粉丝的官方口味. Ubuntu M ...

  7. 让 QQ 邮箱更好用,支持桌面通知

    前言 腾讯家的 QQ 邮箱和企业邮箱很好用,之前一直是用着网页版,最多加上个手机 APP 收个推送,反正也不是着急的事儿. 急了 最近因为工作的原因,对收邮件的实时性有了更高的要求. 一开始,我试用了 ...

  8. 使用ES6,Pt更好JavaScript。 III:酷收藏和闪烁的弦

    介绍 ( Introduction ) ES2015 brings some heavy-hitting changes to the language, such as promises and g ...

  9. JavaScript 简史

    本文转载自:众成翻译 译者:网络埋伏纪事 审校: 为之漫笔 链接:http://www.zcfy.cc/article/2389 原文:https://auth0.com/blog/a-brief-h ...

最新文章

  1. Scrum团队初建的十一件事——Scrum中文网
  2. 生成有关 SQL Server 2005 Analysis Services 多维数据集数据源的本地化报表
  3. 前Duolingo秦龙博士归国创业:情定K12个性化学习
  4. FSMO角色以及DC修复
  5. IIS7 设置 UrlRewrite
  6. Socket编程:之TCP案例
  7. c语言的point函数,C语言中friend友元函数详细解析
  8. ubuntu下使用visual studio code来编译和调试C++
  9. grafana 批量添加图表
  10. 什么时候建立分区的时候需要建立EFI分区
  11. 2020你一直在苦找的Ps插件全在这!20款Photoshop实用插件分享
  12. DL之RNN:人工智能为你写歌词(林夕写给陈奕迅)——基于TF利用RNN算法实现【机器为你作词】、训练测试过程全记录
  13. 【迁移学习】PointDAN: A Multi-Scale 3D Domain Adaption Network for Point Cloud Representation
  14. macM1 出现 zsh: command not found: brew问题解决方案
  15. 【干货】怎么将阿里云ECS的数据下载到本地
  16. tekton入门 - 起步
  17. 2022年5月20日最全摸鱼游戏导航
  18. Windows SDK for Windows 7安装流程
  19. 《查令十字街84号》读后感
  20. 服务器桌面监控,GitHub - 373137461/wallpaper_monitor: 适用于 Wallpaper Engine 等桌面壁纸软件的服务器状态监控软件,使用 PHP 开发...

热门文章

  1. mallcloud商城基于SpringBoot2.x
  2. 千博HTML5自适应企业网站系统源码
  3. 漂亮的页面过渡动画源码
  4. md函数MySQL_MySQL的常用SQL语句.md
  5. html中擦窗效果,最有效的清洁窗户窗框方法有哪些,怎样清洁效果最好?
  6. Unknown column 'password_lifetime' in 'field list';创建数据库时创建用户,修改用户时报错
  7. Git详细安装教程,翻译
  8. oracle 1408,Oracle 11.2.0.2 Patch 说明
  9. mysql数据类型的验证_MYSQL数据类型详解
  10. 详解CSS的盒模型(box model) 及 CSS3新增盒模型计算方式box-sizing