《Understanding ES6》 chapter2 Strings and Regular Expressions

242 阅读4分钟

第二章 字符串和正则表达式

(一)字符串

更好的Unicode支持

Es6之前,是采用固定的16位字符编码(UCS-2)为基础,每个16位序列都是一个码元(code unit),用于表示一个字符。字符串所有的属性如length和方法如charAt()都基于16位的码元。

UTF-16码点

码点类似于字符编码,用一个数字来代表一个字符,是全球唯一标识符。

UTF-16码点可以由多个码元组成。

ES6新增方法,支持UTF-16

Es6之前的旧方法 Es6新增方法 方法作用
charCodeAt() codePointAt() 给定字符串中按位置提取的unicode码点
String.fromCharCode() String.fromCodePoint() 用给定的码点来产生包含单个字符的字符串
let str = "𠮷a";
str.charCodeAt(0); //55362
str.charCodeAt(1); //57271
str.charCodeAt(2); //97

str.codePointAt(0); //134071
str.codePointAt(1); //57271
str.codePointAt(2); //97

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

normalize()方法:指定Unicode的标准形式,参数有以下四种:

  • NFC,默认参数,表示“标准等价合成”(Normalization Form Canonical Composition),返回多个简单字符的合成字符。所谓“标准等价”指的是视觉和语义上的等价。
  • NFD,表示“标准等价分解”(Normalization Form Canonical Decomposition),即在标准等价的前提下,返回合成字符分解的多个简单字符。
  • NFKC,表示“兼容等价合成”(Normalization Form Compatibility Composition),返回合成字符。所谓“兼容等价”指的是语义上存在等价,但视觉上不等价,比如“囍”和“喜喜”。(这只是用来举例,normalize方法不能识别中文。)
  • NFKD,表示“兼容等价分解”(Normalization Form Compatibility Decomposition),即在兼容等价的前提下,返回合成字符分解的多个简单字符。

识别子字符串的方法:

  • includes():返回布尔值,表示是否找到了参数字符串。
  • startsWith():返回布尔值,表示参数字符串是否在原字符串的头部。
  • endsWith():返回布尔值,表示参数字符串是否在原字符串的尾部。

都有两个参数,第一个参数是要查找的子字符串,第二个参数是搜索的位置。使用第二个参数n时,endsWith的行为与其他两个方法有所不同。它针对前n个字符,而其他两个方法针对从第n个位置直到字符串结束。

let s = 'Hello world!';

s.startsWith('world', 6) // true
s.endsWith('Hello', 5) // true
s.includes('Hello', 6) // false

repeat()方法: 接受一个参数n作为重复的次数,返回一个将初始字符串重复n次的新字符串。

(二)正则表达式

u修饰符:用于正确处理大于\uFFFF的UTF-16编码

y修饰符:粘连,从正则表达式lastIndex属性值得位置开始搜索,如果在该位置没有匹配成功,将停止搜索。

注意:

  1. y修饰符只有正则表达式对象上的方法才有,如exec()和test(),字符串上的方法并不会体现粘连特性;
  2. 当用^来匹配字符创的起始处时,粘连的正则表达式只会匹配字符串的起始位置,或在多行模式下匹配行首。所以,当lastIndex不对应字符串的起始位置和多行模式下的行首位置时,粘连的正则表达式永远不会匹配成功。

sticky属性:返回布尔值,检测正则表达式中是否存在y修饰符

flag属性:获取正则表达式的修饰符

var r = /hello\d/y;
r.sticky; // true
r.flag; //'y'

2019-6-10

(三)模板字面量

模板字面量解决的问题:

  • 多行字符串;
  • 基本的字符串格式化:使用已存在的变量值,对字符串进行部分替换的能力;
  • HTML转义
  1. 多行字符串

在模板字符串中使用单引号和双引号不需要转义,使用反引号(`)用反斜杠(\)转义;

推荐的模板字面量写法:

let html = `
<div>
	<h1>Title</h1>
</div>
`.trim();
  1. 产生替换位

${ JS表达式 }:可以放本地变量,函数,计算式,其他模板字面量等等。

标签化模板

let message = tag`Hello World`;
function tag(literals, ...substituions) {
  
}
let count = 10,
		price = 0.25,
		message = passthru`${count} items cost $${(count * price).toFixed(2).}`;

// passthru(literals,...substituions)函数的参数值为:
// literals数组值为["", " items cost $", "."] ; 包含raw属性, literals[0]总是等价于literals.raw[0]
// substituions数组值为[10,2.50]

可以交替使用literals和substituions数组的值来模拟模板字面量的默认行为。

String.raw(): 获取原始字符串值

let msg1 = `Hello\nWorld`,
    msg2 = String.raw`Hello\nWorld`; 
console.log(msg1); //Hello
									 //World
console.log(msg2); //Hello\\nworld

可以用literals.raw模拟String.raw():

function (literals, ...substituions) {
  let result = "";
  
  //使用substituions的元素长度来进行循环
  for(let i = 0; i < substituions[i];.length; i++) {
    result += literals.raw[i]; //改为使用原始值
    result += substituions[i];
  }
  //添加最后一个字面量
  result += literals.raw[literals.length-1];
  return result;
}

let msg = raw`Hello\nWorld`;
console.log(msg);
console.log(msg.length);