ES9新特性:
1异步迭代
在async/await,你可能在同步循环中调用异步函数,例如:
async function process(array){ for(let i of array){ await dosomething(i) } }
这段代码不会正常运行,下面这段也不会正常运行:
async function process(array){ array.forEach(async i => { await dosomething(i); }) }
这段代码中,循环本身依旧保持同步,并在内部异步函数之前全部调用完毕。
ES2018引入异步迭代器(asynchronous iterators),这就像常规迭代器,除了next()方法返回一个promise。因此await可以和for...of循环一起使用,以串行的方式异步运作
async function process(array){ for await (let i of array){ dosomething(i) } }
2.Promise.finally()
一个promise调用链要么成功到达最后一个.then(),要么失败触发.catch()。在某些情况下,你想要在无论Promise运行成功还是失败,运行相同的代码,例如清除,删除对话,关闭数据连接等。
.funally()允许你指定最终的逻辑:
function dosomething(){ dosomething1() .then(dosomething2) .then(dosomething3) .catch(err => { console.log(err); }) .finally(() => {}); }
3.Rest/Spread
解构和扩展
4.正则表达式命名捕获组(groups)
js正则表达式可以返回一个匹配对象--一个包含匹配字符串的累数组,例如以YYYY-MM-DD的格式解析日期:
const reDate = /([0-9]{4})-([0-9]{2})-([0.-9]{2})/, match = reDate.exec("2019-04-12"), year = match[1], mouth = match[2], day = match[3]
这样的代码很难读懂,并且改变正则表达式的结构有可能改变匹配对象的索引
ES2018允许命名捕获组使用?<name>,在打开捕获括号(后立即命名,示例:
const reDate = /(?<year>[0-9]{4})-(?<mouth>[0-9]{2})-(?<day>[0-9]{2})/, match = reDate.exec("2019-04-12"), year = match.groups.year, mouth = match.groups.mouth, day = match.groups.day
5正则表达式反向断言
目前js支持先行断言(lookahead),这意味着匹配会发生,但不会有任何捕获,并且断言没有包含在整个匹配字符字段中,例如:
const reLookahead = /D(?=d+)/, match = reLookahead.exec("$123.23") console.log(match[0]) //$
ES2018引入以相同方式工作但是匹配前面的反向断言(lookbehind),这样我就可以忽略货币符号,单纯的捕获价格数字:
const reLookbehind = /(?<=D)d+/, match = reLookbehind.exec("$123.23") console.log(match[0]) //123
6正则表达式dotAll模式
正则表达式中点.匹配除回车以外的任何单字符,标记s改变这种方式,允许终止符的出现,例如:
/hello.world/.test("hello world"); /hello.world/s.test("hello world");
ES10新特性
1.行分隔符(U + 2028)和段分隔符(U + 2029)符号现在允许在字符串文字中,与JSON匹配
以前,这些符号在字符串文字中被视为行终止符,因此使用它们会导致SyntaxError异常。
2.更加友好的 JSON.stringify
如果输入 Unicode 格式但是超出范围的字符,在原先JSON.stringify返回格式错误的Unicode字符串。现在实现了一个改变JSON.stringify的第3阶段提案,因此它为其输出转义序列,使其成为有效Unicode(并以UTF-8表示)
3.新增了Array的 flat()
方法和 flatMap()
方法
flat()
和 flatMap()
本质上就是是归纳(reduce) 与 合并(concat)的操作。
Array.prototype.flat()
flat()
方法会按照一个可指定的深度递归遍历数组,并将所有元素与遍历到的子数组中的元素合并为一个新数组返回。
var arr1 = [1,2,[3,4]]; arr1.flat();//[1,2,3,4]; var arr2 = [1,2,[3,4,[5,6]]]; arr2.flat(); //[1,2,3,4,[5,6]]; var arr3 = [1,2,[3,4,[5,6]]]; arr3.flat(2);//[1,2,3,4,5,6] 参数表示展开的深度
其次,还可以利用 flat()
方法的特性来去除数组的空项
var arr4 = [1,2,,4,5] arr4.flat();//[1,2,4,5]
Array.prototype.flatMap()
flatMap()
方法首先使用映射函数映射每个元素,然后将结果压缩成一个新数组。它与 map 和 深度值1的 flat 几乎相同,但 flatMap 通常在合并成一种方法的效率稍微高一些。 这里我们拿map方法与flatMap方法做一个比较。
var arr1 = [1,2,3,5]; arr1.map(x => [x*2]) //(4) [Array(1), Array(1), Array(1), Array(1)]0: [2]1: [4]2: [6]3: arr1.flatMap(x => [x*2]) //(4) [2, 4, 6, 10] arr1.flatMap(x => [[x*2]]) //(4) [Array(1), Array(1), Array(1), Array(1)]
4.新增了String的 trimStart()
方法和 trimEnd()
方法
新增的这两个方法很好理解,分别去除字符串首尾空白字符,这里就不用例子说声明了。
5. Object.fromEntries()
Object.entries()
方法的作用是返回一个给定对象自身可枚举属性的键值对数组,其排列与使用 for...in 循环遍历该对象时返回的顺序一致(区别在于 for-in 循环也枚举原型链中的属性)。
而 Object.fromEntries()
则是 Object.entries()
的反转。
通过 Object.fromEntries, 可以将 Map 转化为 Object:
const map1 = new Map([['foo','bar'],['baz',42]]) const obj122 = Object.fromEntries(map1) obj1 //{foo: "bar", x: 41}
通过 Object.fromEntries, 可以将 Array 转化为 Object:
var obj32 = Object.fromEntries(arr1) var obj32 = Object.fromEntries(arr21) obj32 //{0: "a", 1: "b", 2: "c"}
6. String.prototype.matchAll
matchAll()
方法返回一个包含所有匹配正则表达式及分组捕获结果的迭代器。 在 matchAll 出现之前,通过在循环中调用regexp.exec来获取所有匹配项信息(regexp需使用/g标志
7. Function.prototype.toString()
现在返回精确字符,包括空格和注释
头部和尾部的注释不显示
9.修改 catch
绑定
之前是try {}catch(e){}
现在是try {}catch{}
10.新的基本数据类型 BigInt
其中数据类型:String、Number、Boolean、Null、Undefined、Symbol、BigInt