ES6 学习笔记(3) 字符串扩展

1. 字符串的Unicode表示方法


javaScript允许采用\uxxxx形式表示字符串, xxxx表示字符的unicode码点
这种表示法只限于\u0000 --\uFFFF之间的字符, 超出这个范围必须使用双字节

  '\u0061'  // a
  '\uD847\uDFB7'  // '吉'

es6对超过码点进行的改进,只需将码点放入大括号就能正确读解该字符

  '\u{1F680}' === '\uD83D\uDE80'
  // true

有了这之后JavaScript有六种方法表示一个字符

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

2. codePoinAt()


JavaScript内部,字符已UTF-16的格式存储,每个字符固定为2个字节,.对于那些需要4个字节存储的的字符(unicode码点大于0xFFFF),会认为他们是两个字符 。
codPoinAt能够正确处理4个字节存储的字符返回一个字符的码点

  var s = '吉';
  s.length     // 2
  s.chart(0)  // "
  s.chart(1)  // ''
  s.charCodeAt(0)  // 55362
  s.charCodeAt(1)  // 57271

  s.codePointAt(0)  //134071
  s.codePoinAt(1)  //57271

总之,codePointAt方法会正确返回 32 位的 UTF-16 字符的码点。对于那些两个字节储存的常规字符,它的返回结果与charCodeAt方法相同。

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

  let s = 'a';
  s.codePointAt(0).toString(16) // "20bb7"
  s.codePointAt(2).toString(16) // "61"

codePointAt方法是测试一个字符是由两个字节还是四个字节组成的最简单的方法

3. String.fromCodePoint()


ES5中String.fromcharCode方法用于从码点返回对应字符,但是不能识别32位的UTF-16字符(unicode编号大于0xFFFF).

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

ES6 提供了String.fromCodePoin放大可识别大于0xFFFF的字符 作用上与codePionAt相反

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

4. 字符串遍历接口


ES6 为字符串添加了遍历器接口,使得字符串可以被for...of循环遍历。

  for (let code in 'foo') {
    console.log(code)  //  'f' 'o' 'o'
  }

5. at()


ES5 提供了chartAt方法,返回字符串的给定位置的字符 该方法不能识别码点大于0xFFFF的字符
目前,有一个提案,提出字符串实例的at方法,可以识别 Unicode 编号大于0xFFFF的字符,返回正确的字符。

6. normalize()


normalize方法可以接受一个参数来指定normalize的方式,参数的四个可选值如下。

  • NFC,默认参数,表示“标准等价合成”(Normalization Form Canonical Composition),返回多个简单字符的合成字符。所谓“标准等价”指的是视觉和语义上的等价。
  • NFD,表示“标准等价分解”(Normalization Form Canonical Decomposition),即在标准等价的前提下,返回合成字符分解的多个简单字符。
  • NFKC,表示“兼容等价合成”(Normalization Form Compatibility Composition),返回合成字符。所谓“兼容等价”指的是语义上存在等价,但视觉上不等价,比如“囍”和“喜喜”。(这只是用来举例,normalize方法不能识别中文。)
  • NFKD,表示“兼容等价分解”(Normalization Form Compatibility Decomposition),即在兼容等价的前提下,返回合成字符分解的多个简单字符。
    不过,normalize方法目前不能识别三个或三个以上字符的合成。这种情况下,还是只能使用正则表达式,通过 Unicode 编号区间判断。

7. includes() , startsWith() , endsWith()


  • includes() : 返回布尔值 , 表示是否找到参数字符串
  • startsWith() : 返回布尔值 , 表示参数字符串是否在原字符串头部
  • endsWith() : 返回布尔值 , 表示参数字符串是否在原字符串尾部
    都支持第二个参数表示开始搜索的位置 (endsWith 针对前 n个字符)
  let s = 'hello' ;
  s.startsWith('h')  // true
  s.endsWith('o')  // true
  s.includes('ll' , 0)    // true

8. repeat()


repeat() 方法返回一个新的字符串,表示将原字符串重复n

  'x'.repeat(3)  // 'xxx'
  // 参数如果是小数,会被取整
   'x'.repeat(2.9)  // 'xxx'
  // 参数如果是负数,或者```Infinity```,会报错
   'x'.repeat(Infinity)  //  Error
  // 0-1之间的小数  和 NaN 等同于0 
  // 参数是字符串则会先转换成数字
  'na'.repeat('na')  // ''
  'na'.repea('3')   // 'nanana'

9. padStart() , padEnd()


ES8 引入了字符串全长度补全功能.padStart()补全头部,padEnd()补全尾部

  'x'.padStart(6 , 'abc')   // 'abcabx'
  'x'.padEnd(6, 'abc')     // 'xabcab'
  // 第一个参数为最小长度, 第二个为补全的字符串
  // 如果原字符串的长度 等于或大于指定的最小长度,则返回原字符串
  `xxx`.padStart(2 , 'a')  //  'xxx'
  // 如果原字符串和补全字符串的长度之和超过制定最小长度,则会截去补全字符串超出的位数
  'xxxxxx'.padEnd(10,'aaaaaaaa')  // 'xxxxxxaaaa'
  // 如果省略第二个参数, 默认使用空格补全长度
  'a'.padStart(5)  // '    a'

常见用途

  // padStart的常见用途是为数值补全指定位数。下面代码生成 10 位的数值字符串
  '1'.padStart(10, '0') // "0000000001"
  '12'.padStart(10, '0') // "0000000012"
  '123456'.padStart(10, '0') // "0000123456"
  // 另一个用途是提示字符串格式。
  '12'.padStart(10, 'YYYY-MM-DD') // "YYYY-MM-12"
  '09-12'.padStart(10, 'YYYY-MM-DD') // "YYYY-09-12"

10. matchAll()


matchAll方法返回一个正则表达式在当前字符串的所有匹配

11. 模板字符串


  • 模板字符串(template string)是增强版的字符串,用反引号(`)标识。它可以当作普通字符串使用,也可以用来定义多行字符串,或者在字符串中嵌入变量。
  // 普通字符串
  `In JavaScript `\n` is a line-feed`
  // 多行模板字符串
  ` In JavaScript 
     is a line-feed `
  console.log(`string text line 1 
               string text line 2`);
  // 字符串中嵌入变量
  // 模板字符串中嵌入变量,需要将变量名写在${}之中。
  let name = "Bob", time = "today";
  `Hello ${name}, how are you ${time}?`
  • 模板字符串要用反引号表示, 如果在模板字符串中需要使用反引号 则需反斜杠转译
  • 模板字符串的空格和换行都是被保留的 如果不想要 可以使用trim消除
  $('#list').html(`
    
  • first
  • second
`.trim());
  • 大括号内部可以放入任意的 JavaScript 表达式,可以进行运算,以及引用对象属性。
  • 模板字符串之中还能调用函数。
  • 如果大括号中的值不是字符串,将按照一般的规则转为字符串。比如,大括号中是一个对象,将默认调用对象的toString方法。
  • 如果模板字符串中的变量没有声明,将报错。
  • 模板字符串甚至还能嵌套。

12. [模板编译] (http://es6.ruanyifeng.com/#docs/string)

13. [标签模板] (http://es6.ruanyifeng.com/#docs/string)


模板字符串的功能,不仅仅是上面这些。它可以紧跟在一个函数名后面,该函数将被调用来处理这个模板字符串。这被称为“标签模板”功能(tagged template)。

14. String.raw()


  • String.raw方法,往往用来充当模板字符串的处理函数,返回一个斜杠都被转义(即斜杠前面再加一个斜杠)的字符串,对应于替换变量后的模板字符串。
  String.raw`Hi\n${2+3}!`;
  // 返回 "Hi\\n5!"

  String.raw`Hi\u000A!`;
  // 返回 "Hi\\u000A!"

  String.raw`Hi\\n`
  // 返回 "Hi\\\\n"
  • String.raw方法可以作为处理模板字符串的基本方法,它会将所有变量替换,而且对斜杠进行转义,方便下一步作为字符串来使用。
  • String.raw方法也可以作为正常的函数使用。这时,它的第一个参数,应该是一个具有raw属性的对象,且raw属性的值应该是一个数组。
  String.raw({ raw: 'test' }, 0, 1, 2);
  // 't0e1s2t'

  // 等同于
  String.raw({ raw: ['t','e','s','t'] }, 0, 1, 2);
  • 作为函数,String.raw的代码实现基本如下。
String.raw = function ( String , ...values) {
  let output = ''  ;
  let index 
  for (index = 0 ;index < values.length ;index++) {
    optput += strings.raw[index] + values[index]; 
  }
  output += strings.raw[index]
  return output
}

15. 模板字符串的限制

\u和\x在 LaTEX 里面有特殊含义,但是 JavaScript 将它们转义了。
ES2018 放松了对标签模板里面的字符串转义的限制。如果遇到不合法的字符串转义,就返回undefined,而不是报错,并且从raw属性上面可以得到原始字符串。
这种对字符串转义的放松,只在标签模板解析字符串时生效,不是标签模板的场合,依然会报错。

你可能感兴趣的:(ES6 学习笔记(3) 字符串扩展)