ES2017 新特性:
async
函数Object.values/Object.entries
- 字符串填充:
String.prototype.padStart()
和String.prototype.padEnd()
Object.getOwnPropertyDescriptors()
- 函数参数列表和调用中的尾随逗号
ES8 引入了 async
函数。async
函数基本上是 co 的专用语法:
async function fetchJson(url) {
try {
let request = await fetch(url)
let text = await request.text()
return JSON.parse(text)
} catch (error) {
console.log(`ERROR: ${error.stack}`)
}
}
在内部,async
函数的工作方式与 Generator 非常相似,但它们不会转换为生成器函数。
异步函数存在以下变体:
- 异步函数声明:
async function foo() {}
- 异步函数表达式:
const foo = async function () {}
- 异步方法定义:
let obj = { async foo() }
- 异步箭头函数:
const foo = async () => {}
进一步阅读:
Object.values()
是一个与 Object.keys()
类似的新方法,但返回的是 Object
自身属性的所有值,不包括继承的值。
假设我们要遍历如下对象 obj
的所有值:
const obj = {
a: 1,
b: 2,
c: 3,
[Symbol()]: 123
}
以前的写法如下:
const val = Object.keys(obj).map((key) => obj[key])
console.log(val) // [1, 2, 3]
使用 Object.values()
:
const val = Object.values(obj)
console.log(val) // [1, 2, 3]
从上述代码中可以看出 Object.values()
为我们省去了遍历 key,并根据这些 key 获取 value 的步骤。
注意:您可能注意到了,它会忽略键为
Symbol
的属性,Object.keys
、Object.values
,以及接下来的Object.entries
也一样。
Object.entries()
方法接受一个对象(可枚举)作为参数,并返回一个数组。
以下是遍历 obj
对象的所有属性的 key
和 value
:
const obj = {
a: 1,
b: 2,
c: 3
}
Object.keys(obj).forEach((key) => {
console.log(`key: ${key}, value: ${obj[key]}`)
})
// key: a, value: 1
// key: b, value: 2
// key: c, value: 3
使用 Object.entries()
:
for (let [key, value] of Object.entries(obj)) {
console.log(`key: ${key} value: ${value}`)
}
// key: a, value: 1
// key: b, value: 2
// key: c, value: 3
Object.entries()
还允许您通过对象设置 map
。这比使用二维数组更简洁,但键只能是字符串。
let map = new Map(
Object.entries({
one: 1,
two: 2
})
)
console.log(JSON.stringify([...map])) // [["one",1],["two",2]]
假如您有一个午餐订单对象,以及订购的每件商品的数量。
let lunch = {
soup: 2,
bread: 1,
sandwich: 3,
lemonade: 7,
tea: 2,
pastaSalad: 4
}
您想从订购最多到订购最少的顺序订购这些。
我们可以使用 entries
方法将对象转为数组,保留 key/value
关系,在使用 sort
排序:
let sorted = Object.entries(lunch).sort((a, b) => {
if (a[1] > b[1]) return -1
return 1
})
/*
[
[ 'lemonade', 7 ],
[ 'pastaSalad', 4 ],
[ 'sandwich', 3 ],
[ 'soup', 2 ],
[ 'tea', 2 ],
[ 'bread', 1 ]
]
*/
Object.getOwnPropertyDescriptors()
方法返回对象的所有自身属性的属性描述符。如果没有,则返回空对象。
const obj = {
name: 'UI',
get age() {
return 18
},
[Symbol('foo')]: 123
}
console.log(JSON.stringify(Object.getOwnPropertyDescriptors(obj), null, 2))
/*
{
"name": {
"value": "UI",
"writable": true,
"enumerable": true,
"configurable": true
},
"age": {
"enumerable": true,
"configurable": true
}
}
*/
在 ES8 中 String
新增了两个实例函数 padStart()
和 padEnd()
,其接受两个参数,第一个是重复次数,第二个是要添加的字符串,并在给定字符串的开头或结尾填充。
语法:
String.prototype.padStart(maxLength, (fillString = ' '))
String.prototype.padEnd(maxLength, (fillString = ' '))
如果字符串比 maxLength
短,使用 fillString
填充剩余长度:
'0.0'.padStart(5, '10') // '100.0'
如果字符串和 maxLength
一样长,或者比 maxLength
更长,则原样返回:
'abcd'.padStart(4, '*') // abcd
'abcdefg'.padStart(4, '*') // 'abcdefg'
如果 fillString
省略,则使用默认值,包含单个空格的字符串 ' '
:
'x'.padStart(3) // ' x'
padEnd
与 padStart
类似,一个用于开头,一个用于末尾。
在 ES8 之前,我们只有在对象字面量和数组字面量中的尾随逗号才被忽略:
let obj = {
first: 'D.',
last: 'O'
}
let arr = ['red', 'green', 'blue']
console.log(arr.length) // 3
它有两个好处:
- 重新排列项目更简单,因为如果最后一个项目改变了它的位置,您不必添加和删除逗号。
- 它帮助版本控制系统跟踪实际更改的内容。方便使用 Git 进行多人协作开发时修改同一个函数减少不必要的行变更。
鉴于可选和忽略尾随逗号的好处,建议的功能是将它们带到参数定义和函数调用中。
const foo = (a) => {}
foo(a)
foo(a)
(a) => {}
和 (a,) => {}
都是有效的函数定义,foo(a)
和 foo(a,)
都是有效的函数调用。