字符Unicode的表示法
javascript允许采用 \uxxxx(Unicode码点)
形式表示一个字符。但是,这种表示法只限于码点在\u0000 ~ \uFFFF
之间的字符,超出这个范围的字符,必须用两个双字节的形式表示。
"\u20BB7"---会理解为 "\u20BB+7" // " 7"
ES6 对这一点做出了改进,只需要将码点放入大括号,就能正确解读该字符
"\u{20BB7}" //"?""\u{41}\u{42}\u{43}" //ABClet hello = 123;hell\u{6F} // 123"\u{1F680}" === "\uD83D\uDE80" // true
有了这种表示法之后,Javascript共有6种方法可以表示一个字符
'\z' === 'z' //true'\172' === 'z' //true'\x7A' === 'z' //true'\u007A' === 'z' //true'\u{7A}' === 'z' //true
codePoint()
JavaScript内部,字符以UTF-16的格式储存,每个字符固定为2个字节。对于那些需要4个字节储存的字符(Unicode码点大于0xFFFF的字符),JavaScript会认为它们是两个字符。
var s = "?";s.length // 2s.charAt(0) // ''s.charAt(1) // ''s.charCodeAt(0) // 55362s.charCodeAt(1) // 57271
ES6提供了 codePointAt
方法,能够正确处理4个字节储存的字符,返回一个字符的码点
var s = '?a';s.codePointAt(0) // 134071s.codePointAt(1) // 57271s.codePointAt(2) // 97
codePointAt
方法的参数,是字符在字符串中的位置(从0开始)。上面代码中,JavaScript将“?a”视为三个字符,codePointAt方法在第一个字符上,正确地识别了“?”,返回了它的十进制码点134071(即十六进制的20BB7)。在第二个字符(即“?”的后两个字节)和第三个字符“a”上,codePointAt
方法的结果与charCodeAt
方法相同。
总之,codePointAt
方法会正确返回32位的UTF-16字符的码点。对于那些两个字节储存的常规字符,它的返回结果与charCodeAt
方法相同。
codePointAt
方法返回的是码点的十进制值,如果想要十六进制的值,可以使用toString方法转换一下。
var s = '?a';s.codePointAt(0).toString(16) // "20bb7"s.codePointAt(2).toString(16) // "61"
你可能注意到了,codePointAt方法的参数,仍然是不正确的。比如,上面代码中,字符a在字符串s的正确位置序号应该是1,但是必须向codePointAt方法传入2。解决这个问题的一个办法是使用for...of
循环,因为它会正确识别32位的UTF-16字符。
var s = '?a';for (let ch of s) { console.log(ch.codePointAt(0).toString(16));}// 20bb7// 61
codePointAt方法是测试一个字符由两个字节还是由四个字节组成的最简单方法。
function is32Bit(c) { return c.codePointAt(0) > 0xFFFF;} is32Bit("?") // trueis32Bit("a") // false
- for-in 循环用来遍历对象属性;for-of 循环用来遍历数据-例如数组中的值,但是不仅如此它还支持:大多数类数组对象、字符串遍历(将字符串视为一系列的Unicode字符进行遍历)、Map对象遍历、Set对象遍历