All the New ES2019 Tips and Tric

作者: 范小饭_ | 来源:发表于2019-08-24 17:02 被阅读8次

    All the New ES2019 Tips and Tricks
    翻译:范小饭

    ES2019中新的提示和技巧

    随着在ES2019中添加新功能,ECMAScript标准再次更新。现在可以在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
    }
    
    // convert to array in order to make use of .filter() function
    let overTwentyOne = Object.entries(students).filter(([name, age]) => {
      return age >= 21
    }) // [ [ 'beatrice', 22 ], [ 'eloise', 21 ] ]
    
    // turn multidimensional array back into an object
    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
    }
    
    // convert to array in order to make use of .filter() function
    let overTwentyOne = Object.entries(students).filter(([name, age]) => {
      return age >= 21
    }) // [ [ 'beatrice', 22 ], [ 'eloise', 21 ] ]
    
    // turn multidimensional array back into an object
    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 }
    // dropped first beatrice!
    

    使用这些功能时,请务必注意潜在的副作用。

    支持Object.fromEntries的浏览器

    Array.prototype.flat

    多维数组是一种非常常见的数据结构,尤其是在检索数据时。展平它的能力是必要的。它总是可能的,但不完全漂亮。
    让我们看下面的例子,map展平的多维数组。

    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' ]
    // ]
    
    [].concat.apply([], courseStudents) // we're stuck doing something like this
    

    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'
    // ]
    

    这个决定的因为让函数在默认情况下不贪婪,并且需要明确的指令来操作。对于未知深度,旨在完全展平阵列,可以使用Infinity的参数。

    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

    随着增加了flat,我们也得到了一个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 = [].concat.apply([], curved) // now flatten, could use flat but that didn't exist before either
    // [
    //  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 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'
    

    可选的捕获绑定

    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' +
    //  '}'
    

    这主要是一个内部的变化,但我忍不住认为这也可能使一两个博客作者的生活更轻松。


    现在你已经知道了ES2019的主要特色。

    还有一些您可能想要探索的其他新增内容。那些包括:

    Happy JavaScript coding!

    相关文章

      网友评论

        本文标题:All the New ES2019 Tips and Tric

        本文链接:https://www.haomeiwen.com/subject/nglqectx.html