ES2018 里包括哪些新特性?
栏目: JavaScript · 发布时间: 6年前
内容简介:我们一路奋战,不是为了改变世界,而是为了不让世界改变我们。——《熔炉》JavaScript 标准 ECMAScript 的推进是非常活跃的了,自 ES2015 开始,标准制定委员会 TC39 决定每年为一个周期,推出新版本标准,这无疑为 JavaScript 语言本身注入了强大的活力。
我们一路奋战,不是为了改变世界,而是为了不让世界改变我们。
——《熔炉》
JavaScript 标准 ECMAScript 的推进是非常活跃的了,自 ES2015 开始,标准制定委员会 TC39 决定每年为一个周期,推出新版本标准,这无疑为 JavaScript 语言本身注入了强大的活力。
一个新特性在写入标准前,一般需要经过 5 个阶段:
- Stage 0 - Strawman(展示阶段):最初提交的想法。
- Stage 1 - Proposal(征求意见阶段):一个正式提案文档,且至少有一位 TC39 的成员支持,其中包括 API 示例。
- Stage 2 - Draft(草案阶段):特性规范的初始版本,具有两个实验性实现。
- Stage 3 - Candidate(候选人阶段):对提案规范进行评审,并从第三方厂商收集反馈。
- Stage 4 - Finished(定案阶段):提案已经准备好包含在 ECMAScript 中,但是在浏览器和 Node.js 中可能需要一些时间实现。
一个提案只要能进入 Stage 2,就差不多肯定会包括在以后的正式标准里面。ECMAScript 当前的所有提案,可以在 TC39 的官方网站 GitHub.com/tc39/ecma26… 查看。
在正式讲解 ES2018 前,先回顾一下 ES2016 和 ES2017 中引入的新特性。
ES2016
-
数组的
includes方法 -
指数运算符
**,比如a ** b和Math.pow(a, b)的效果一样
ES2017
- 异步函数
-
Object.values,返回由对象属性值组成的数组 -
Object.entries,返回由一个个由[key, vlaue]组成的数组 -
Object.getOwnPropertyDescriptors,返回一个对象,包含目标对象身上所有的属性描述符(.value、.writable、.get、.set、.configurable、.enumerable) -
字符串的
padStart和padEnd方法 - 定义对象、声明数组以及在函数的参数列表中,可使用尾逗号。
-
用来读取和写入到共享内存的
SharedArrayBuffer和Atomics。
好了,现在来看下 ES2018 增加的新特性吧 :heart_eyes:。
ES2018
异步迭代
如果一个异步函数中包含一个循环,循环里的每一次迭代是发起一个异步请求。那么怎么保证在本次迭代的请求完成后,再继续进入下一次迭代呢?
你可能想过像下面这样做:
async function process(array) {
for (let i of array) {
await fetch(`https://jsonplaceholder.typicode.com/todos/${i}`)
}
}
复制代码
但是不行的。
那么这样呢?也不行。☹️
// 这样也不行
async function process(array) {
array.forEach(async i => {
await fetch(`https://jsonplaceholder.typicode.com/todos/${i}`)
})
}
复制代码
因为循环本身是同步的,不会等里面的异步请求完成后再进入下一次迭代的。
ES2018 引入了异步迭代器,与普通迭代器不同的是,异步迭代器的 next
方法返回的是一个 Promise。因此, await
关键字用在 for...of
之前,可以完成一系列按特定顺序发生的 请求->等待->完成->进入下一次迭代
的操作流程。例如:
// 这样 OK :smiley:
async function process(array) {
for await (let i of array) {
await fetch(`https://jsonplaceholder.typicode.com/todos/${i}`)
}
}
复制代码
Promise.finally()
.finally()
方法总是会被执行,无论 Promise 最终状态是 resolve 了,还是 reject 了。类似于 try...catch...finally
里的 finally
块的作用。
async function process(array) {
fetch('https://jsonplaceholder.typicode.com/todos/1')
.then(response => response.json())
.then(json => console.log(json))
.catch(error => {
console.log(error)
})
.finally(() => {
// 这里的代码总是会被执行
// 无论 Promise 最终状态是 resolve 了,还是 reject 了
})
}
复制代码
剩余/扩展属性
ES2015 引入了三个点( ...
)运算符,这个运算符既能用来收集函数的剩余参数,也可以用来扩展数组。
首先来看作为剩余参数运算符的例子:
doSomething(1, 2, 3, 4, 5)
function doSomething(p1, p2, ...p3) {
// p1 的值为 1
// p2 的值为 2
// p3 是一个数组,值为 [3, 4, 5]
}
复制代码
再来看用做扩展运算符的例子:
const values = [99, 100, -1, 48, 16]; console.log( Math.max(...values) ); // 100 复制代码
我们可以看到,扩展运算符与剩余参数运算符的用法是互为反向的。
ES2015 引入的 ...
运算符,实际上仅适应在对数组的操作上,ES2018 对其进行了增强,将扩展和收集参数的能力扩大到了对象。使得 ...
运算符也可以用来收集对象的“剩余属性”。
一个基础的例子:
const obj = { a: 1, b: 2, c: 3 }
const { a, ...x } = obj
// a 等于 1
// x 的值为 { b: 2, c: 3 }
复制代码
这里的 a
对应的是 obj
的属性 a
; x
则是由 obj
中除 a
属性以外的其他属性组成的对象。
我们借用这个例子里的 obj
,再来看一个例子:
doSomething(obj)
function doSomething({ a, ...x }) {
// a = 1
// x = { b: 2, c: 3 }
}
复制代码
doSomething
函数接收一个对象参数,调用后,将这个对象拆分成变量 a
和 x
。
我们也可以使用 ...
运算符的扩展功能,将一个对象“扩展”进另一个对象。
const obj1 = { a: 1, b: 2, c: 3 };
const obj2 = { ...obj1, z: 26 };
// obj2 值变成了 { a: 1, b: 2, c: 3, z: 26 }
复制代码
使用这个特性,我们还可以实现对象的浅克隆: obj2 = { ...obj1 }
。
正则表达式的命名捕获组
在 ES2018 之前,我们如果要匹配类似 '2018-04-30'
这样的字符串格式,可能会这样做。
const
reDate = /([0-9]{4})-([0-9]{2})-([0-9]{2})/,
match = reDate.exec('2018-04-30'),
year = match[1], // 2018
month = match[2], // 04
day = match[3]; // 30
复制代码
我们从最终的匹配结果 match
身上,使用索引值,找到对应捕获组匹配的内容。但带来的一个问题是,之后如果匹配格式发生改变,那么 match
对应索引值下内容的含义就不一样了。这样我们势必会修改代码,来提供正确的逻辑。
而 ES2018 允许我们为捕获组命名,命名方式是在 (
前面使用符号 ?<name>
标识。
const
reDate = /(?<year>[0-9]{4})-(?<month>[0-9]{2})-(?<day>[0-9]{2})/,
match = reDate.exec('2018-04-30'),
year = match.groups.year, // 2018
month = match.groups.month, // 04
day = match.groups.day; // 30
复制代码
所有的命名组的匹配结果,可以在结果对象的 groups
属性中获得。没有命中的捕获组,取值时得到 undefined
。
除此之外,命名捕获组还可以在字符串的 replace
方法中使用:
const
reDate = /(?<year>[0-9]{4})-(?<month>[0-9]{2})-(?<day>[0-9]{2})/,
d = '2018-04-30',
usDate = d.replace(reDate, '$<month>-$<day>-$<year>');
复制代码
这里我们将 '2019-05-18'
格式化为 '05-18-2019'
。在替换字符串中,使用 $<name>
的形式加入该命名捕获组匹配到的内容。
正则表达式的后行断言
JavaScript 正则表达式天然支持前行断言。
所谓前言断行,是指 x
只有在 y
前面时才匹配,书写形式如 /x(?=y)/
。比如,下面的例子里,我们只匹配数字之前的美元符号:
const
reLookahead = /\$(?=\d+)/,
match = reLookahead.exec('$123');
console.log( match[0] ); // $
复制代码
对应地,所谓后行断断言,是指 x
只有在 y
后面时才匹配,书写形式如 /(?<=y)x/
。同样上面的例子,我们只匹配美元符号之后的数字:
const
reLookahead = /(?<=\$)\d+/,
match = reLookahead.exec('$123');
console.log( match[0] ); // 123
复制代码
正则表达式的 s 修饰符:dotAll 模式
正则表达式的 .
匹配任意字符,但有两个例外:
-
不能识别码点大于
0xFFFF的 Unicode 字符,这些字符每个占用 4 个字节。 -
终止符:包括换行符(
\n)、回车符(\r)在内的字符。
针对第一条限制,我们可以使用 u
修饰符解决;针对第二条限制,我们则可以使用 s
修饰符。
// . 不匹配 \n,所以正则表达式返回 false
/hello.world/.test('hello\nworld') // false
// 这样就可以了
/hello.world/s.test('hello\nworld') // true
复制代码
正则表达式的 Unicode 属性类
ES2018 引入了一种新的类的写法 \p{...}
和 \P{...}
,允许正则表达式匹配符合 Unicode 某种属性的所有字符。
const regexGreekSymbol = /\p{Script=Greek}/u;
regexGreekSymbol.test('π') // true
复制代码
上面代码中, \p{Script=Greek}
指定匹配一个希腊文字母,所以匹配 π
成功。
\P{…}
是 \p{…}
的反向匹配,即匹配不满足条件的字符。
注意,这两种类只对 Unicode 有效,所以使用的时候一定要加上 u
修饰符。如果不加 u
修饰符,就会报错。
模板字符串微调
在 JavaScipt 中,字符串中的 \
表示一个转义字符,它提供了 5 种表达字符的方式:
'\z' === 'z' // true(z 无特殊含义,直接输出)
'\172' === 'z' // true(字符的八进制表示)
'\x7A' === 'z' // true(字符的十六进制表示)
'\u007A' === 'z' // true(字符的十六进制表示)
'\u{7A}' === 'z' // true(字符的十六进制表示,支持任意 Unicode 字符码点)
复制代码
这就带来了一个问题,如果字符串中包含 \unicode
或 \xerxes
的话,就会报错,因为会被认为是无效的字符转义。
为了解决这个问题,ES2018 放松了对标签模板里面的字符串转义的限制。如果遇到不合法的字符转义,就返回 undefined
,而不是报错,并且可以从 raw
属性上面可以得到原始字符串。
function tag(strs) {
// strs[0] 等于 undefined
// strs.raw[0] 等于 "\\unicode and \\u{55}";
}
tag`\unicode and \u{55}`
复制代码
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- 包括外部php文件
- Php包括恼人的上边距
- jQuery submit()不包括提交的按钮
- 记录一次搜狐面试(包括笔试题)
- 数据中台到底包括什么内容?一文详解架构设计与组成
- 人工智能技术主要包括五大类型,你知道几个?
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
The Algorithmic Beauty of Plants
Przemyslaw Prusinkiewicz、Aristid Lindenmayer / Springer / 1996-4-18 / USD 99.00
Now available in an affordable softcover edition, this classic in Springer's acclaimed Virtual Laboratory series is the first comprehensive account of the computer simulation of plant development. 150......一起来看看 《The Algorithmic Beauty of Plants》 这本书的介绍吧!