ES2019新特性

2019-08-211412次阅读javascript

ECMAScript标准在ES2019中添加了新功能,再次进行了更新。现在在node、chrome、firefox和safari中正式提供,如果需要支持较旧的浏览器,还可以使用babel将这些功能编译成不同版本的javascript。

 

Object.fromEntries

在ES2017中介绍了Object.entries。这是一个将对象转换为数组表示的函数。

let students = {
  amelia: 20,
  beatrice: 22,
  cece: 20,
  deirdre: 19,
  eloise: 21
}

Object.entries(students) 
// [
//  [ 'amelia', 20 ],
//  [ 'beatrice', 22 ],
//  [ 'cece', 20 ],
//  [ 'deirdre', 19 ],
//  [ 'eloise', 21 ]
// ]

这是一个很好的补充,因为它允许对象使用Array原型中内置的众多函数。像map、filter、reduce等。不幸的是,要将结果转换回对象,需要一些手动的过程。

let students = {
  amelia: 20,
  beatrice: 22,
  cece: 20,
  deirdre: 19,
  eloise: 21
}

//转换为数组以便使用filter()函数
let overTwentyOne = Object.entries(students).filter(([name, age]) => {
  return age >= 21
}) // [ [ 'beatrice', 22 ], [ 'eloise', 21 ] ]

//将多维数组转换回对象
let DrinkingAgeStudents = {}
for (let [name, age] of overTwentyOne) {
    DrinkingAgeStudents[name] = age;
}
// { beatrice: 22, eloise: 21 }

Object.fromEntries旨在删除该循环!它为您提供了更简洁的代码,邀请您在对象上使用数组原型方法。

let students = {
  amelia: 20,
  beatrice: 22,
  cece: 20,
  deirdre: 19,
  eloise: 21
}

//转换为数组以便使用filter()函数
let overTwentyOne = Object.entries(students).filter(([name, age]) => {
  return age >= 21
}) // [ [ 'beatrice', 22 ], [ 'eloise', 21 ] ]

//将多维数组转换回对象
let DrinkingAgeStudents = Object.fromEntries(overTwentyOne); 
// { beatrice: 22, eloise: 21 }

值得注意的是,数组和对象是不同的数据结构,这是有原因的。在某些情况下,两者之间的切换会导致数据丢失。下面的数组元素成为重复的对象键的例子就是其中之一。

let students = [
  [ 'amelia', 22 ], 
  [ 'beatrice', 22 ], 
  [ 'eloise', 21], 
  [ 'beatrice', 20 ]
]

let studentObj = Object.fromEntries(students); 
// { amelia: 22, beatrice: 20, eloise: 21 }
// [ 'beatrice', 22 ]被重置

使用这些功能时,请确保了解潜在的副作用。

 

Array.prototype.flat

多维数组是一种非常常见的数据结构,尤其是在检索数据时。

let courses = [
  {
    subject: "math",
    numberOfStudents: 3,
    waitlistStudents: 2,
    students: ['Janet', 'Martha', 'Bob', ['Phil', 'Candace']]
  },
  {
    subject: "english",
    numberOfStudents: 2,
    students: ['Wilson', 'Taylor']
  },
  {
    subject: "history",
    numberOfStudents: 4,
    students: ['Edith', 'Jacob', 'Peter', 'Betty']
  }
]

let courseStudents = courses.map(course => course.students)
// [
//   [ 'Janet', 'Martha', 'Bob', [ 'Phil', 'Candace' ] ],
//   [ 'Wilson', 'Taylor' ],
//   [ 'Edith', 'Jacob', 'Peter', 'Betty' ]
// ]
Array.prototype.concat.apply([], courseStudents)
//["Janet", "Martha", "Bob", [ 'Phil', 'Candace' ], "Wilson", "Taylor", "Edith", "Jacob", "Peter", "Betty"]

在Array.prototype.flat中。它需要一个可选的深度参数。

let courseStudents = [
  [ 'Janet', 'Martha', 'Bob', [ 'Phil', 'Candace' ] ],
  [ 'Wilson', 'Taylor' ],
  [ 'Edith', 'Jacob', 'Peter', 'Betty' ]
]

let flattenOneLevel = courseStudents.flat(1)
console.log(flattenOneLevel)
// [
//   'Janet',
//   'Martha',
//   'Bob',
//   [ 'Phil', 'Candace' ],
//   'Wilson',
//   'Taylor',
//   'Edith',
//   'Jacob',
//   'Peter',
//   'Betty'
// ]

let flattenTwoLevels = courseStudents.flat(2)
console.log(flattenTwoLevels)
// [
//   'Janet',   'Martha',
//   'Bob',     'Phil',
//   'Candace', 'Wilson',
//   'Taylor',  'Edith',
//   'Jacob',   'Peter',
//   'Betty'
// ]

请注意,如果没有给定参数,则默认深度为1。这是非常重要的,因为在我们的示例中,数组不会完全变平。

let courseStudents = [
  [ 'Janet', 'Martha', 'Bob', [ 'Phil', 'Candace' ] ],
  [ 'Wilson', 'Taylor' ],
  [ 'Edith', 'Jacob', 'Peter', 'Betty' ]
]

let defaultFlattened = courseStudents.flat()
console.log(defaultFlattened)
// [
//   'Janet',
//   'Martha',
//   'Bob',
//   [ 'Phil', 'Candace' ],
//   'Wilson',
//   'Taylor',
//   'Edith',
//   'Jacob',
//   'Peter',
//   'Betty'
// ]

这个决定的理由是,函数在默认情况下不是贪婪的,因此需要显式的指令来进行操作。对于意图完全展平数组的未知深度,可以使用无穷大的参数。

let courseStudents = [
  [ 'Janet', 'Martha', 'Bob', [ 'Phil', 'Candace' ] ],
  [ 'Wilson', 'Taylor' ],
  [ 'Edith', 'Jacob', 'Peter', 'Betty' ]
]

let alwaysFlattened = courseStudents.flat(Infinity)
console.log(alwaysFlattened)
// [
//   'Janet',   'Martha',
//   'Bob',     'Phil',
//   'Candace', 'Wilson',
//   'Taylor',  'Edith',
//   'Jacob',   'Peter',
//   'Betty'
// ]

和往常一样,贪婪的操作应该谨慎使用,如果数组的深度确实未知,那么贪婪的操作可能不是一个好的选择。

 

Array.prototype.flatMap

我们希望将元素插入到数组中。在ES2019之前,我们可能这样处理。

let grades = [78, 62, 80, 64]

let curved = grades.map(grade => [grade, grade + 7])
// [ [ 78, 85 ], [ 62, 69 ], [ 80, 87 ], [ 64, 71 ] ]

let flatMapped = Array.prototype.concat.apply([], curved)
// [
//  78, 85, 62, 69,
//  80, 87, 64, 71
// ]

现在我们有了array.prototype.flat,我们可以稍微改进这个示例。

let grades = [78, 62, 80, 64]

let flatMapped = grades.map(grade => [grade, grade + 7]).flat()
// [
//  78, 85, 62, 69,
//  80, 87, 64, 71
// ]

随着flatMap我们可以这样做:

let grades = [78, 62, 80, 64]

let flatMapped = grades.flatMap(grade => [grade, grade + 7]);
// [
//  78, 85, 62, 69,
//  80, 87, 64, 71
// ]

记住Array.prototype.flat默认参数是1。而flatMap相当于map与flat不带参数。所以flatMap只会展开一级。

let grades = [78, 62, 80, 64]

let flatMapped = grades.flatMap(grade => [grade, [grade + 7]]);
// [
//   78, [ 85 ],
//   62, [ 69 ],
//   80, [ 87 ],
//   64, [ 71 ]
// ]


String.trimStart and String.trimEnd

ES2019中另一个不错的补充是一个别名,它使一些字符串函数名称更加清晰。以前,String.trimRight并且String.trimLeft可用。

let message = "   Welcome to CS 101    "
message.trimRight()
// '   Welcome to CS 101'
message.trimLeft()
// 'Welcome to CS 101   '
message.trimRight().trimLeft()
// 'Welcome to CS 101'

这些都是很好的功能,但给它们命名更符合其目的也是有益的。删除起始空格和结束空格。

let message = "   Welcome to CS 101    "
message.trimEnd()
// '   Welcome to CS 101'
message.trimStart()
// 'Welcome to CS 101   '
message.trimEnd().trimStart()
// 'Welcome to CS 101'


可选的catch绑定

ES2019中的另一个好特性是在try-catch块中进行参数可选。以前,所有catch块都作为参数传入异常。这意味着即使catch块中的代码忽略了它,它也存在。

try {
  let parsed = JSON.parse(obj)
} catch(e) {
  // ignore e, or use
  console.log(obj)
}

情况不再是这样了。如果catch块中没有使用异常,则根本不需要传入任何内容。

try {
  let parsed = JSON.parse(obj)
} catch {
  console.log(obj)
}

如果您已经知道错误是什么,并且正在寻找触发错误的数据,那么这是一个很好的选择。

 

Function.toString()更改

ES2019也改变了Function.toString()的操作方式。以前,它完全删除了空白区域。

function greeting() {
  const name = 'CSS Tricks'
  console.log(`hello from ${name}`)
}

greeting.toString()
//'function greeting() {\nconst name = \'CSS Tricks\'\nconsole.log(`hello from ${name} //`)\n}'

现在它反映了源代码中函数的真实表示。

function greeting() {
  const name = 'CSS Tricks'
  console.log(`hello from ${name}`)
}

greeting.toString()
// 'function greeting() {\n' +
//  "  const name = 'CSS Tricks'\n" +
//  '  console.log(`hello from ${name}`)\n' +
//  '}'


其它新增内容包括如下:

上一篇: nodejs重定向  下一篇: Request简化的HTTP客户端Streaming流学习  

ES2019新特性相关文章