ES6标准入门 第四章:字符串的扩展

Posted 见证LBJ

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ES6标准入门 第四章:字符串的扩展相关的知识,希望对你有一定的参考价值。

1、字符串的Unicode 表示法

 

javascript 允许采用 \uxxxx 表示一个字符,其中 xxxx 表示字符的码点

"\u0061"     // "a"

 

ES5中的缺陷:

以上表示法只限于 \u0000——\uFFFF 之间的字符。超出这个范围的=字符,必须用两个双字节表示。

"\uD842\uDFB7"    //"??"

 

如果直接在\u 后面直接加上超过\uFFFF 的数值:

"\u20BB7"     // "  7"

如上代码,JavaScript会理解成  “\u20BB+7” 。由于\u20BB 是一个不可打印字符, 所以显示一个空格。

 

ES6的改进:

只要将码点放入大括号,就能正确解读改字符。

"\u{20BB7}"    // "??"

"\u{41}\u{42}\u{43}"     // "ABC"

let hello = 123;
hell\u{6F} // 123
‘\u{1F680}‘ === ‘\uD83D\uDE80‘ // true 此行代码表示:大括号表示法 与 四字节的UTF-16编码是等价的。

 

在JavaScript 中共有6种方法可以表示一个字符:

‘\z‘ === ‘z‘  // true
‘\172‘ === ‘z‘ // true
‘\x7A‘ === ‘z‘ // true
‘\u007A‘ === ‘z‘ // true
‘\u{7A}‘ === ‘z‘ // true

 


 

2、codePointAt()

 

JavaScript 内部,字符以UTF-16 的格式存储,每个字符固定为2字节。 对于Unicode 码点大于0xFFFF 的字符(需要4个字节存储),js会认为它们是2 个字符。

 

ES5的缺陷:

var s = "??";

s.length // 2
s.charCodeAt(0) // 55362
s.charCodeAt(1) // 57271

上面的代码中,?? 的码点是0x20BB7,UTF-16 编码为0xD842 0xDFB7(十进制为55362 57271),需要4个字节储存。

对于这种四字节字符,JavaScript不能正确处理,字符串长度会被误认为2;charCodeAt 方法只能分别返回前两个字节的值 和 后两个字节的值。

 

ES6 的改进:

提供了codePointAt方法,能够正确处理4 字节字符,返回一个32位的UTF-16字符的码点。(返回的码点是十进制的)

let s = ‘??a‘;

s.codePointAt(0) // 134071
s.codePointAt(1) // 57271
s.codePointAt(2) // 97

参数为字符在字符串中的位置(从0开始); 对于两个字节存储的常规字符,它的返回结果与charCodeAt方法相同。

 

若要codePointAt方法返回的是十六进制的值,可以使用 toString方法转换一下。

let s = ‘??a‘;

s.codePointAt(0).toString(16) // "20bb7"
s.codePointAt(2).toString(16) // "61"

 

以上代码仍然存在问题:codePointAt方法的参数仍然是不正确的。【a在字符串的位置是1, 但是传参却是2】

解决方法: 使用for…of 循环,因为它可以正确识别32位的 UTF-16字符。

let s = ‘??a‘;
for (let i of s) {
   console.log( i.codePointAt(0).toString(16) );
}
// "20bb7"
// "61"

 

codePointAt 方法 是测试一个字符由 2个字节 还是 4个字节 组成的最简单的方法。

function is32Bit( c ) {
   return c.codePiontAt(0) > 0xFFFF;
}
is32Bit("
??"); // true

is32Bit("a"); // true

 


 

3、String.fromCodePoint()

 

ES5 的缺陷:

String.fromCharCode 用于从码点返回对应的字符,但是不能识别大于Unicode编码 0xFFFF 的字符(32位的UTF-16字符)

String.fromCharCode(0x20BB7)
// "?"

上面代码 0x20BB7发生溢出最高位两位被舍弃,最后返回码点U+0BB7对应的字符,而不是码点U+20BB7对应的字符。

 

ES6的改进:

String.fromCodePoint 方法,可以识别大于0xFFFF 的码点;作用上正好与 codePointAt 相反

String.fromCodePoint(0x20BB7)
// "??"
String.fromCodePoint(0x78, 0x1f680, 0x79) === ‘x\uD83D\uDE80y‘
// true

方法中有多个参数,则它们会被合并成一个字符串返回。

 

注意: fromCodePoint 方法定义在 String对象上, 而codePointAt 方法定义在字符串的实例对象上。

 

以上是关于ES6标准入门 第四章:字符串的扩展的主要内容,如果未能解决你的问题,请参考以下文章

《ES6标准入门》数组的扩展

重读 ES6 标准入门(第3版)

《ES标准入门》&《UNDERSTANDING ECMACHRIPT 6》 读书摘录笔记(上)

es6入门教程完整版

ES6入门教程---解构赋值和字符串扩展

《ES6标准入门》29~48Page 字符串拓展 正则拓展