Skip to content

Latest commit

 

History

History
248 lines (186 loc) · 6 KB

ES2017(ES8).md

File metadata and controls

248 lines (186 loc) · 6 KB

ES2017(ES8)

ES2017 新特性:

  • async 函数
  • Object.values/Object.entries
  • 字符串填充:String.prototype.padStart()String.prototype.padEnd()
  • Object.getOwnPropertyDescriptors()
  • 函数参数列表和调用中的尾随逗号

async 函数

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.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.keysObject.values,以及接下来的 Object.entries 也一样。

Object.entries()

Object.entries() 方法接受一个对象(可枚举)作为参数,并返回一个数组。

以下是遍历 obj 对象的所有属性的 keyvalue

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()

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
  }
}
*/

String.prototype.padStart() 和 String.prototype.padEnd()

在 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'

padEndpadStart 类似,一个用于开头,一个用于末尾。

函数参数列表和调用中的尾随逗号

在 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,) 都是有效的函数调用。