You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
if (!String.prototype.codePointAt) {
(function() {
'use strict'; // needed to support `apply`/`call` with `undefined`/`null`
var codePointAt = function(position) {
if (this == null) {
throw TypeError();
}
var string = String(this);
var size = string.length;
// `ToInteger`
var index = position ? Number(position) : 0;
if (index != index) { // better `isNaN`
index = 0;
}
// Account for out-of-bounds indices:
if (index < 0 || index >= size) {
return undefined;
}
// Get the first code unit
var first = string.charCodeAt(index);
var second;
if ( // check if it’s the start of a surrogate pair
first >= 0xD800 && first <= 0xDBFF && // high surrogate
size > index + 1 // there is a next code unit
) {
second = string.charCodeAt(index + 1);
if (second >= 0xDC00 && second <= 0xDFFF) { // low surrogate
// http://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae
return (first - 0xD800) * 0x400 + second - 0xDC00 + 0x10000;
}
}
return first;
};
if (Object.defineProperty) {
Object.defineProperty(String.prototype, 'codePointAt', {
'value': codePointAt,
'configurable': true,
'writable': true
});
} else {
String.prototype.codePointAt = codePointAt;
}
}());
}
javascript处理汉字到unicode的转换
最近项目中发现个问题,就是javascript的String.fromCharCode对超过两个字节的unicode不能很好的返回对应的字。
测试如下:
也就是说 只要超出了两个字节的unicode,js都没有很好的解析。
事实上,不仅仅是fromCharCode,javascript里面大部分字符处理函数都无法很好的处理超过两个字节的字符的问题。
##汉字的unicode区间
我们一直都认为汉字是双字节的,实际上根据unicode5.0规范。汉字的范围如下:
可以看到 其中 CJK统一汉字扩充B的范围就不是双字节的。上面提到的"𠂇"就在这个范围里。当然大部分的汉字都是双字节的。
CJK统一汉字扩充B的汉字我们可以在这看到个大概:
http://www.chinesecj.com/code/ext-b.php
更加完整的unicode范围,可以参考这个文章,虽然年代有些久远。
##javascript的编码
javascript之所以会有这样的问题,是因为javascript使用了一种叫做UCS-2的编码方式。UCS-2编码只能处理两个字节的字符。而对于
0x20087
这种不止两个字节的,他会拆成两个双子节的字符。对于上面的
0x20087
它会拆成两个双字节0xd840
,0xdc87
。然后分别解析发现都是"",就造成了上面的现象。具体的转换公式为:更加具体的javascript的编码历史,可以参考阮一峰的文章。
##es6的解决方案
在es6的规范里,已经针对这种双字节的问题做了处理,提供了几个方法:
于是我们可以这样:
不过很显然支持性很一般。
mdn有相关的兼容处理,具体方法就是
fromCodePoint的实现:
codePointAt的实现:
有了上面的兼容处理,我们就可以很好的处理unicode与多字节字符之间的转换了。
##结语
作为10天设计出来的语言,javascript总是有这样那样的坑,实在是让人很无奈。总是要让人花一大堆时间擦屁股。
The text was updated successfully, but these errors were encountered: