最近在看阮一峰老师写的《ES6标准入门》
其中第五章的代码让我产生了疑惑
代码如下:
var s = '𠮷𠮷';
s.length // 4
string.length
字符串的属性在工作中经常用到,但是并没有出现上述问题呀。
例如:
'你好'.length //2
咦~这就让我很疑惑了,为什么我输出字符串长度是能够正确显示,而书中却显示的错误的。我又把老师的代码拿出来跑一遍,'𠮷𠮷'.length
确实是4,没有问题。
注意这里的 ‘ 𠮷 ’ 并非吉利的 ‘ 吉 ’。
而且在我工作中经常使用此属性判断中文字符串的长度。这让我产生了探究原因的动力。
猜想:可能是Unicode对中文的标识方式不同导致的
随即,翻阅了Unicode中文编码,印证了我的猜想。
下面附上Unicode中文表示范围,以供参考
一般使用2W个基本汉字就够了 | ||
---|---|---|
字符集 | 汉字 | unicode编码 |
基本汉字 | 20902字 | 4E00-9FA5 |
基本汉字补充 | 38字 | 9FA6-9FCB |
扩展A | 6582字 | 3400-4DB5 |
扩展B | 42711字 | 20000-2A6D6 |
扩展C | 4149字 | 2A700-2B734 |
扩展D | 222字 | 2B740-2B81D |
康熙部首 | 214字 | 2F00-2FD5 |
部首扩展 | 115字 | 2E80-2EF3 |
兼容汉字 | 477字 | F900-FAD9 |
问题原因
JavaScript采用\uxxxx的形式来标识一个字符,其中xxxx标识Unicode码点。
但是在ES5以及之前,这种标识方法只限于码点在\u0000~\uFFFF之间的字符。超出这个范围的字符,必须用2个双字节的形式表示。
"\uD842\uDfb7" //𠮷
"\u20BB7" // 7
上面代码表示,如果直接在 \u 后面跟上大于 0xFFFF 的数值(比如 \u20BB7)。JavaScript会理解为 \u20BB7+7。由于 \u20BB7 不是一个可以打印的字符,所以显示为一个空格,后面跟一个7.
这就是为什么'𠮷'.length; //4
的原因了
ES6对这一问题做了改进,只要将码点放入大括号中,就能正确的解读该字符。
"\u{20BB7}" //𠮷
解决办法
使用ES6语法规则
function codePointLength(text){
var result = text.match(/[\s\S]/gu);
return result ? result.length : 0
}
感想:阮一峰的《ES6标准入门》确实是一本很好的书,他将ES6将近全部内容用通俗的语言和简单易懂的例子展现出来,通过这本书我查缺补漏,确实学到了很多。我觉得这本书被命名为标准入门,确实低估了它对ES6知识范围的包含度。可能是阮一峰老师比较谦虚的原因吧,谦虚也是大师的风范。
网友评论