ES——ES2018和2019的新规范
一、规范
1、解除模版字符串限制 - Lifting template literal restriction
“Lifting template literal restriction” 翻译过来为 “解除模版字符串限制”,这个要结合 ES6 中的 “带标签的模版字符串” 来理解。
以下代码执行时,解析器会去查找有效的转义序列,例如 Unicode 字符以 "\u" 开头,例如 \u00A9,以下 "\unicode" 是一个非法的 Unicode 字符,在之前就会得到一个 SyntaxError: malformed Unicode character escape sequence 错误。ES2018 中解除了这个限制,当遇到不合法的字符时也会正常执行,得到的是一个 undefined,通过 raw 属性还是可以取到原始字符串。
function latex(strings, ...exps) {
console.log(strings); // [ undefined ]
console.log(strings.raw); // [ 'latex \\unicode' ]
}
latex`latex \unicode`;
2、JSON 超集
ES2019 之前 JSON 字符串中不支持 \u2028(行分隔符)、\u2029(段落分隔符) 字符,否则 JSON.parse() 会报错,现在给予了支持。
const json = '"\u2028"';
JSON.parse(json);
3、JSON.stringify() 加强格式转化
防止 JSON.stringify 返回格式错误的 Unicode 字符串,参考 https://2ality.com/2019/01/well-formed-stringify.html
二、方法
1、 异步迭代
异步迭代在 Node.js 中用的会多些,使用 for-await-of 遍历异步数据。例如使用 MongoDB 查询数据返回值默认为一个游标对象,避免了一次性把数据读入应用内存,详情参考 https://github.com/qufei1993/blog/issues/31。
const userCursor = userCollection.find();
for await (const data of userCursor) { ... }
2、Promise.finally
Promise.finally 能保证无论执行成功或失败都一定被执行,可以用来做一些清理工作。
const connection = { open: () => Promise.resolve() }
connection
.open()
.then()
.catch()
.finally(() => {
console.log('clear connection');
})
3、新的正则表达式功能
- 正则命名组捕获
正则命名组捕获使用符号 ?<name> 表示,对匹配到的正则结果按名称访问。
const regexp = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/u;
const result = regexp.exec('2023-01-01');
console.log(result.groups); // { year: '2023', month: '01', day: '01' }
- 正则 Lookbehind 断言:https://github.com/tc39/proposal-regexp-lookbehind
- 正则表达式dotAll模式:https://github.com/tc39/proposal-regexp-dotall-flag
- 正则表达式 Unicode 转义:https://github.com/tc39/proposal-regexp-unicode-property-escapes
4、Rest/Spread 属性
Rest 参数语法使用 ... 表示,会将所有未明确的参数表示为一个数组。
const fn = (a, ...rest) => {
console.log(a, rest); // 1 [ 2, 3 ]
}
fn(1, 2, 3);
展开操作符(Spread)也使用 ... 表示,将一个数组内容转换为参数传递给函数。
const fn = (a, ...rest) => {
console.log(a, rest); // 1 [ 2, 3 ]
}
fn(...[1, 2, 3]);
展开操作符另一个常用的场景是用来做对象的浅拷贝。
const obj = { a: 1 }
const newObj = { ...obj, b: 2 }
5、可选的 catch 参数
try {
throw new Error('this is not a valid')
} catch {
console.error(`error...`);
}
6、Symbol.prototype.description
创建 Symbol 对象时可以传入一个描述做为参数。如下所示,使用 symbol.description 可方便的获取到这个描述。
const symbol = Symbol('Hello World')
symbol.description
7、函数的 toString() 方法
函数也可以执行 toString() 方法,它会返回定义的函数体代码,包含注释。
const fn = (a, b) => {
// return a + b value
const c = a + b;
return c;
}
console.log(fn.toString());
8、Object.fromEntries
Object.fromEntries() 方法会把键值对列表转换为对象。同 Object.entries() 相反。
const arr = [ [ 'name', 'foo' ], [ 'age', 18 ] ];
const obj = Object.fromEntries(arr);
console.log(obj); // { name: 'foo', age: 18 }
console.log(Object.entries(obj)); // [ [ 'name', 'foo' ], [ 'age', 18 ] ]
9、消除前后空格
ES2019 之前有一个 trim() 方法会默认消除前后空格。新增的 trimStart()、trimEnd() 方法分别用来指定消除前面、后面空格。
' JavaScript '.trim() // 'JavaScript'
' JavaScript '.trimStart() // 'JavaScript '
' JavaScript '.trimEnd() // ' JavaScript'
10、数组 flat()、flatMap()
flat(depth) 可以实现数组扁平化,传入的 depth 参数表示需要扁平化的数组层级。
[['a'], ['b', 'bb'], [['c']]].flat(2) // [ 'a', 'b', 'bb', 'c' ]
flatMap() 方法是 map() 和 flat() 方法的结合,该方法只能展开一维数组。
[['a'], ['b', 'bb'], [['c']]].flatMap(x => x) // [ 'a', 'b', 'bb', [ 'c' ] ]

浙公网安备 33010602011771号