今天阅读了一篇咨询,有关于ES7-ES10 (ES2016-2019),ES6后新出的特性比较频繁。
首先附上思维导图
下面都是我阅读咨询后理解而编写的:
ES7:
1.Array.prototype.includes()
这个方法可以判断一个元素是否在数组上,
这个API接收两个参数 item,index
item 是要判断的值在这里插入代码片
index 从第几个索引开始
这个api跟indexof类似
2.求幂运算符 **
这个运算符类似 Math.pow(2,10)//1024
一个数字的N次方
Math.pow(2,10)//1024
console.log(2**10)//1024
ES8
1.Async/Await
这个特性提供了在不阻塞主线程的情况下使用同步代码访问资源,
这样的好处能解决回调地狱的问题,而且代码更加美观,阅读性更强
注意事项
await与async是一起使用的,不能单独使用
async/await 在通过异步执行后并隐式返回promise作为结果的函数对象
2.Object.values() / Object.entries()
这两个方法为一个对象提供转为数组的作用
Object.values只返回对象的属性值的一维数组
Object.entries返回了key 跟value 的二维数组
属性按照对象的值从小到大进行排序
const obj = { foo: 'bar', baz: 42 };
Object.values(obj) // ["bar", 42]
const obj = { 100: 'a', 2: 'b', 7: 'c' };
Object.values(obj) // ["b", "c", "a"]
const obj = { foo: 'bar', baz: 42 };
Object.entries(obj) // [ ["foo", "bar"], ["baz", 42] ]
const obj = { 10: 'xxx', 1: 'yyy', 3: 'zzz' };
Object.entries(obj); // [['1', 'yyy'], ['3', 'zzz'], ['10': 'xxx']]
3.String.padding 字符串填充
方法接收两个参数
targetLength (必填项) 要填充目标的总长度
padString (选填) 填充的字符串 如果为不赋值,使用“ ”代替
分别有两个方法padStart padEnd
'x'.padStart(4, 'ab') // 'abax'
'x'.padEnd(5, 'ab') // 'xabab'
4.Object.getOwnPropertyDescriptors() 返回描述对象的信息
const obj = {
name: '浪里行舟',
get bar () {
return 'abc'
}
}
console.log(Object.getOwnPropertyDescriptors(obj))
返回结果
ES9
1. for await of
感觉就像是每次循环都会等待循环体的结果再进第二次循环
for of方法能够遍历具有Symbol.iterator接口的同步迭代器数据,但是不能遍历异步迭代器。ES9新增的for await of可以用来遍历具有Symbol.asyncIterator方法的数据结构,也就是异步迭代器,且会等待前一个成员的状态改变后才会遍历到下一个成员,相当于async函数内部的await。现在我们有三个异步任务,想要实现依次输出结果,该如何实现呢?
// for of遍历
function Gen (time) {
return new Promise(function (resolve, reject) {
setTimeout(function () {
resolve(time)
}, time)
})
}
async function test () {
let arr = [Gen(2000), Gen(100), Gen(3000)]
for (let item of arr) {
console.log(Date.now(), item.then(console.log))
}
}
test()
得到如下结果:
上述代码证实了for of方法不能遍历异步迭代器,得到的结果并不是我们所期待的,于是for await of就粉墨登场啦!
function Gen (time) {
return new Promise(function (resolve, reject) {
setTimeout(function () {
resolve(time)
}, time)
})
}
async function test () {
let arr = [Gen(2000), Gen(100), Gen(3000)]
for await (let item of arr) {
console.log(Date.now(), item)
}
}
test()
// 1575536194608 2000
// 1575536194608 100
// 1575536195608 3000
使用for await of遍历时,会等待前一个Promise对象的状态改变后,再遍历到下一个成员。
2.Object Rest Spread ...扩展表达式
要点 :
复制是浅拷贝
相同属性后者生效
const arr1 = [10, 20, 30];
const copy = [...arr1]; // 复制
console.log(copy); // [10, 20, 30]
const arr2 = [40, 50];
const merge = [...arr1, ...arr2]; // 合并
console.log(merge); // [10, 20, 30, 40, 50]
console.log(Math.max(...arr)); // 30 拆解
const obj = {x: {y: 10}};
const copy1 = {...obj};
const copy2 = {...obj};
obj.x.y='浪里行舟'
console.log(copy1,copy2) // x: {y: "浪里行舟"} x: {y: "浪里行舟"}
console.log(copy1.x === copy2.x); // → true
3.Promise.prototype.finally()
这个方法无论是结果状态是成功失败都会走finally这个方法,可以减少then与catch中各写相同的代码逻辑
4.正则的新特性
ES9为正则表达式添加了四个新特性,进一步提高了JavaScript的字符串处理能力。这些特点如下:
-
s (dotAll) 标志
-
命名捕获组
-
Lookbehind 后行断言
-
Unicode属性转义
(1)s(dotAll)flag
正则表达式中,点(.)是一个特殊字符,代表任意的单个字符,但是有两个例外。一个是四个字节的 UTF-16 字符,这个可以用u修饰符解决;另一个是行终止符,如换行符(\n)或回车符(\r),这个可以通过ES9的s(dotAll)flag,在原正则表达式基础上添加s表示:
console.log(/foo.bar/.test('foo\nbar')) // false
console.log(/foo.bar/s.test('foo\nbar')) // true
那如何判断当前正则是否使用了 dotAll 模式呢?
const re = /foo.bar/s // Or, `const re = new RegExp('foo.bar', 's');`.
console.log(re.test('foo\nbar')) // true
console.log(re.dotAll) // true
console.log(re.flags) // 's'
(2)命名捕获组
在一些正则表达式模式中,使用数字进行匹配可能会令人混淆。例如,使用正则表达式/(\d{4})-(\d{2})-(\d{2})/来匹配日期。因为美式英语中的日期表示法和英式英语中的日期表示法不同,所以很难区分哪一组表示日期,哪一组表示月份:
const re = /(\d{4})-(\d{2})-(\d{2})/;
const match= re.exec('2019-01-01');
console.log(match[0]); // → 2019-01-01
console.log(match[1]); // → 2019
console.log(match[2]); // → 01
console.log(match[3]); // → 01
ES9引入了命名捕获组,允许为每一个组匹配指定一个名字,既便于阅读代码,又便于引用。
const re = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/;
const match = re.exec('2019-01-01');
console.log(match.groups); // → {year: "2019", month: "01", day: "01"}
console.log(match.groups.year); // → 2019
console.log(match.groups.month); // → 01
console.log(match.groups.day); // → 01
上面代码中,“命名捕获组”在圆括号内部,模式的头部添加“问号 + 尖括号 + 组名”(?),然后就可以在exec方法返回结果的groups属性上引用该组名。
命名捕获组也可以使用在replace()方法中,例如将日期转换为美国的 MM-DD-YYYY 格式:
const re = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/
const usDate = '2018-04-30'.replace(re, '$<month>-$<day>-$<year>')
console.log(usDate) // 04-30-2018
(3)Lookbehind 后行断言
JavaScript 语言的正则表达式,只支持先行断言,不支持后行断言,先行断言我们可以简单理解为"先遇到一个条件,再判断后面是否满足",如下面例子:
let test = 'hello world'
console.log(test.match(/hello(?=\sworld)/))
// ["hello", index: 0, input: "hello world", groups: undefined]
但有时我们想判断前面是 world 的 hello,这个代码是实现不了的。在 ES9 就支持这个后行断言了:
let test = 'world hello'
console.log(test.match(/(?<=world\s)hello/))
// ["hello", index: 6, input: "world hello", groups: undefined]
(?<…)是后行断言的符号,(?..)是先行断言的符号,然后结合 =(等于)、!(不等)、\1(捕获匹配)。
(4)Unicode属性转义
ES2018 引入了一种新的类的写法\p{...}和\P{...},允许正则表达式匹配符合 Unicode 某种属性的所有字符。比如你可以使用\p{Number}来匹配所有的Unicode数字,例如,假设你想匹配的Unicode字符㉛字符串:
console.log(/\d/u.test(str)); // → false
console.log(/\p{Number}/u.test(str)); // → true
同样的,你可以使用\p{Alphabetic}来匹配所有的Unicode单词字符:
const str = 'ض';
console.log(/\p{Alphabetic}/u.test(str)); // → true
// the \w shorthand cannot match ض
console.log(/\w/u.test(str)); // → false
同样有一个负向的Unicode属性转义模板 \P{...}
console.log(/\P{Number}/u.test('㉛')); // → false
console.log(/\P{Number}/u.test('ض')); // → true
console.log(/\P{Alphabetic}/u.test('㉛')); // → true
console.log(/\P{Alphabetic}/u.test('ض')); // → false
除了字母和数字之外,Unicode属性转义中还可以使用其他一些属性。
ES10
1.Array.prototype.flat()
将多维数组打散
2.Array.prototype.flatMap()
传入方法方法体调整原数组
3.Object.fromEntries()
将一个对象转为二维数组 二维是的第一个索引是属性的key 第二个索引是属性的value
4.String.trimStart String.trimEnd
去掉前面的空格 去掉后面的空格
5.String.protoType.matchAll
可以正则匹配出所有匹配上的转为数组返回
6.try...catch
可以去掉catch的形参(err)
7.bigInt
增加了数据类型
现有数据类型 Number、Null、undefined、String、Boolean、bigInt 、Symbol
8.Function.protoType.toString();
把方法转为字符串打印出来
以上是阅读后理解,文章出自https://mp.weixin.qq.com/s/JuWoahhnEunkOTi4qNtWQg