Javascript (ES7 + ES8) 有什么新东东

翻译至 这里

一些JS的新特性已经揭开了神秘的面纱,但是对于大多数开发者来说,了解一部分特性,一部分还是云里雾里的。所以在这里让我们来看一下这些新的特性。

Object.values/Object.entries:

从Object提取values和key-values的方法对于JS来说不是新东西,在ES2015里我们已经有了Object.keys用来返回对应一个对象拥有的可枚举的属性。但是,如果你为该对象属性提取对应的值,你就不得不执行下面的操作:

1
2
3
4
5
6
7
8
9
10
let obj = { a: "foo", b: "bar" }
Object.keys(obj).forEach(key => {
console.log(`prop ${key}: ${obj[key]}`)
})
/* == RESULTS

prop a : foo
prop b : bar

*/

感谢的是,随着ES2017的到来,我们有了两个更轻松更有利于代码阅读的新的方法去迭代一个Object以及去提取Object.values的值或者Object的条目。

Object.values 返回的是一个数组,包含了可枚举的属性值。因此我们可以使用Array.prototype的方法去迭代这个数据,就像使用.filter()结合ES2015的箭头函数一样,它有一个隐藏的返回函数:

1
2
3
let obj = { a: "foo", b: "bar", c: 1, d: [1, 2, 3, 4] }
Object.values(obj)
.filter(val => typeof val != 'string') // returns: [1, [1, 2, 3, 4]]

另外Object.entries会返回一个包含各个可枚举属性的key-value数据。记住,每个结果项目都是数组格式:

1
2
3
let obj = { a: "foo", b: "bar", c: 1, d: [1, 2, 3, 4] }
JSON.stringify(Object.entries(obj))
// returns: "[["a", "foo"],["b", "bar"],["c", 1],["d", [1,2,3,4]]]"

Asynchronous Iteration

在ES2015里面介绍过迭代器(Iterators),如果你不知道关于迭代器的东东,你可以去看一下这篇文章,但当时它是不能迭代异步数据的,直到现在…

在ES2018里面,它成为了可能!这个改变主要是因为现在迭代器的.next()方法会返回一个Promise。在这个例子里面假设我们通过一个通用的端点来接受一组的数字:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
async function* generateAsyncIterator() {
const arrayOfPromises = [
new Promise((resolve, reject) => {
setTimeout(resolve, 1000, 'foo')
}),
new Promise((resolve, reject) => {
setTimeout(resolve, 1500, 'bar')
}),
new Promise((resolve, reject) => {
setTimeout(resolve, 2000, 'lol')
})
]

let nextIndex = 0
while (nextIndex < arrayOfPromises.length) {
const response = await arrayOfPromises[nextIndex]
nextIndex++
yield response
}
}
async function asyncIteratorFunction() {
let asyncIterator = generateAsyncIterator()

console.log(await asyncIterator.next()) // returns {value: "foo", done: false}
console.log(await asyncIterator.next()) // returns {value: "bar", done: false}
console.log(await asyncIterator.next()) // returns {value: "lol", done: false}
console.log(await asyncIterator.next()) // returns {value: undefined, done: true}
}

在这个例子里我们用一个异步generator去创建一个异步的迭代器工厂,要记住的是这种异步迭代器最适合用在流,generators以及web socket上。为了更好理解这个主题,可以去看一下这篇文章,还有这篇

Promise.Prototype.finally()

Promises自ES2015以后一直存在,这是JS异步开发的一大进步。现在它在很多第三方库上都会实现一个.finally()的方法,主要是当Promise完成或者Rejected以后调用的一个回调函数。我们可以理解为try/catch/finally,finally是绝对会被执行的:

1
2
3
4
promise
.then(result => {···})
.catch(error => {···})
.finally(() => {···})

总结

现在JS语言拥有了大量的新特性,加油吧孩子!