$30 off During Our Annual Pro Sale. View Details »

Practical ES6 for the Modern JavaScript Tinkerer

Practical ES6 for the Modern JavaScript Tinkerer

ES6 is now a standard. We're seeing increasing adoption across the web and the fear of missing out is invading your senses. This talk will introduce you to the most practical aspects of ES6, how to use it today in production, what new features are the most useful, and how to migrate away from your ES5 lifestyle, gradually towards adoption of ES6 features. Eventually, you'll be using ES6 without even realizing you ever made "the switch".

Nicolás Bevacqua

December 03, 2015
Tweet

More Decks by Nicolás Bevacqua

Other Decks in Programming

Transcript

  1. ! @nzgb " @bevacqua
    ponyfoo.com

    View Slide

  2. Practical ES6
    for the Modern JavaScript Tinkerer
    ! @nzgb " @bevacqua
    ponyfoo.com

    View Slide

  3. Goals
    ! @nzgb " @bevacqua
    ponyfoo.com
    Simplicity
    Conciseness
    Expressiveness

    View Slide

  4. ! @nzgb " @bevacqua
    ponyfoo.com
    Object Literals

    View Slide

  5. ! @nzgb " @bevacqua
    ponyfoo.com
    Property Value Shorthand
    var x = 1
    var y = 2
    var position = {
    x: x,
    y: y
    }

    View Slide

  6. ! @nzgb " @bevacqua
    ponyfoo.com
    Property Value Shorthand
    var x = 1
    var y = 2
    var position = {
    x,
    y
    }

    View Slide

  7. ! @nzgb " @bevacqua
    ponyfoo.com
    Method Definition
    var car = {
    position: 0,
    move: function (distance) {
    this.position += distance
    }
    }

    View Slide

  8. ! @nzgb " @bevacqua
    ponyfoo.com
    Method Definition
    var car = {
    position: 0,
    move (distance) {
    this.position += distance
    }
    }

    View Slide

  9. ! @nzgb " @bevacqua
    ponyfoo.com
    Computed Property Name
    function prop (key, value) {
    var result = {}
    result[key] = value
    return result
    }

    View Slide

  10. ! @nzgb " @bevacqua
    ponyfoo.com
    function prop (key, value) {
    var result = {
    [key]: value
    }
    return result
    }
    Computed Property Name

    View Slide

  11. ! @nzgb " @bevacqua
    ponyfoo.com
    function prop (key, value) {
    return { [key]: value }
    }
    Computed Property Name

    View Slide

  12. ! @nzgb " @bevacqua
    ponyfoo.com
    Arrow
    Functions

    View Slide

  13. ! @nzgb " @bevacqua
    ponyfoo.com
    var double = function (value) {
    return value * 2
    }
    Arrow Function
    No function keyword

    View Slide

  14. ! @nzgb " @bevacqua
    ponyfoo.com
    var double = (value) => {
    return value * 2
    }
    Arrow Function
    Fat => arrow instead

    View Slide

  15. ! @nzgb " @bevacqua
    ponyfoo.com
    var double = (value) => {
    return value * 2
    }
    Arrow Function
    Single parameter?
    Implicit (parenthesis)

    View Slide

  16. ! @nzgb " @bevacqua
    ponyfoo.com
    var double = value => {
    return value * 2
    }
    Arrow Function
    Single expression?
    Implicit return, {}

    View Slide

  17. ! @nzgb " @bevacqua
    ponyfoo.com
    var double = value => value * 2
    Arrow Function
    (left, right) => left &&
    'left' || right &&
    'right' || undefined
    But, Avoid complexity!

    View Slide

  18. ! @nzgb " @bevacqua
    ponyfoo.com
    [1, 2, 3, 4, 5]
    .filter(x => x > 2)
    .map(x => x * 2)
    .reduce((x, y) => x + y)
    // <- 24
    Arrow Function
    Improved expressiveness

    View Slide

  19. ! @nzgb " @bevacqua
    ponyfoo.com
    var timer = {
    seconds: 0,
    start: function () {
    var add = () => this.seconds++
    setInterval(add, 1000)
    }
    }
    Arrow Function
    Lexical scoping

    View Slide

  20. ! @nzgb " @bevacqua
    ponyfoo.com
    Classes

    View Slide

  21. ! @nzgb " @bevacqua
    ponyfoo.com
    function Cat () {
    this.hunger = 0
    setInterval(() => this.hunger++, 500)
    }
    Cat.prototype.eat = function () {
    this.hunger -= 20
    }
    Classes
    Prototypal inheritance

    View Slide

  22. ! @nzgb " @bevacqua
    ponyfoo.com
    class Cat {
    constructor () {
    this.hunger = 0
    setInterval(() => this.hunger++, 500)
    }
    eat () {
    this.hunger -= 20
    }
    }
    Classes
    Syntactic class sugar

    View Slide

  23. class Cat {
    constructor () {
    this.hunger = 0
    setInterval(() => this.hunger++, 500)
    }
    eat () {
    this.hunger -= 20
    }
    }
    ! @nzgb " @bevacqua
    ponyfoo.com
    Classes
    There's no commas

    View Slide

  24. class Cat {
    constructor () {
    this.hunger = 0
    setInterval(() => this.hunger++, 500)
    }
    eat () {
    this.hunger -= 20
    }
    }
    ! @nzgb " @bevacqua
    ponyfoo.com
    Classes
    Method definition syntax

    View Slide

  25. class Cat {
    constructor () {
    this.hunger = 0
    setInterval(() => this.hunger++, 500)
    }
    eat () {
    this.hunger -= 20
    }
    }
    ! @nzgb " @bevacqua
    ponyfoo.com
    Classes
    Constructor as a method

    View Slide

  26. class Cat {
    constructor () {
    this.hunger = 0
    setInterval(() => this.hunger++, 500)
    }
    static eat (cat) {
    cat.hunger -= 20
    }
    }
    ! @nzgb " @bevacqua
    ponyfoo.com
    Classes
    Explicitly static methods

    View Slide

  27. class WildCat extends Cat {
    constructor () {
    super('wild', 'cat')
    this.hunger = 40
    }
    }
    ! @nzgb " @bevacqua
    ponyfoo.com
    Classes
    Standarized inheritance model
    Explicit super constructor call

    View Slide

  28. ! @nzgb " @bevacqua
    ponyfoo.com
    Destructuring

    View Slide

  29. ! @nzgb " @bevacqua
    ponyfoo.com
    var position = {
    x: 1,
    y: 2
    }
    var x = position.x
    var y = position.y
    Destructuring

    View Slide

  30. ! @nzgb " @bevacqua
    ponyfoo.com
    var position = {
    x: 1,
    y: 2
    }
    var {x} = position
    var {y} = position
    Destructuring

    View Slide

  31. ! @nzgb " @bevacqua
    ponyfoo.com
    var position = {
    x: 1,
    y: 2
    }
    var {x,y} = position
    Destructuring

    View Slide

  32. ! @nzgb " @bevacqua
    ponyfoo.com
    var position = {
    x: 1,
    y: 2
    }
    var {x: posX} = position
    Destructuring

    View Slide

  33. ! @nzgb " @bevacqua
    ponyfoo.com
    var position = {
    x: 1,
    y: 2
    }
    var {x,y,z} = position
    // z is undefined
    Destructuring

    View Slide

  34. ! @nzgb " @bevacqua
    ponyfoo.com
    var position = {
    x: 1,
    y: 2
    }
    var {x,y,z=0} = position
    // z is 0
    Destructuring

    View Slide

  35. ! @nzgb " @bevacqua
    ponyfoo.com
    var person = {
    p: { x: 1,
    y: 2 }
    }
    var {p:{x,y}} = person
    Destructuring

    View Slide

  36. ! @nzgb " @bevacqua
    ponyfoo.com
    var empty = {}
    var {not:{here}} = empty
    // throws: empty.not.here
    Destructuring
    not is undefined

    View Slide

  37. ! @nzgb " @bevacqua
    ponyfoo.com
    var position = [1, 2]
    var x = position[0]
    var y = position[1]
    Destructuring
    Before ES6

    View Slide

  38. ! @nzgb " @bevacqua
    ponyfoo.com
    var position = [1, 2]
    var [x,y] = position
    Destructuring
    Destructuring an array

    View Slide

  39. ! @nzgb " @bevacqua
    ponyfoo.com
    var position = [1, 2, 0]
    var x = position[0]
    var z = position[2]
    Destructuring
    Before ES6

    View Slide

  40. ! @nzgb " @bevacqua
    ponyfoo.com
    var position = [1, 2, 0]
    var [x,,z] = position
    Destructuring
    Skipping indices

    View Slide

  41. ! @nzgb " @bevacqua
    ponyfoo.com
    var left = 20
    var right = 10
    var aux = left
    left = right
    right = aux
    Destructuring

    View Slide

  42. ! @nzgb " @bevacqua
    ponyfoo.com
    var left = 20
    var right = 10;
    [right, left] = [left, right]
    Destructuring
    Swapping, destructured

    View Slide

  43. ! @nzgb " @bevacqua
    ponyfoo.com
    function (base, m) {
    return base * (m || 2)
    }
    Destructuring
    Defaults before ES6

    View Slide

  44. ! @nzgb " @bevacqua
    ponyfoo.com
    function (base, m=2) {
    return base * m
    }
    Destructuring
    Defaults via destructuring

    View Slide

  45. ! @nzgb " @bevacqua
    ponyfoo.com
    Destructuring
    Also in arrow functions
    (base, m=2) => base * m

    View Slide

  46. ! @nzgb " @bevacqua
    ponyfoo.com
    Destructuring
    Anywhere in parameter list
    (x=1,y=2,z=3) => x+y+z

    View Slide

  47. ! @nzgb " @bevacqua
    ponyfoo.com
    Destructuring
    Destructure objects, too!
    (options={a:true}) => {
    console.log(options)
    }

    View Slide

  48. ! @nzgb " @bevacqua
    ponyfoo.com
    Destructuring
    Or the whole parameter list
    ({a=true, b=1}) => {
    console.log(a, b)
    }

    View Slide

  49. ! @nzgb " @bevacqua
    ponyfoo.com
    Destructuring
    Default to an empty object
    ({a=true, b=1}={}) => {
    console.log(a, b)
    }

    View Slide

  50. ! @nzgb " @bevacqua
    ponyfoo.com
    Rest Parameters

    View Slide

  51. ! @nzgb " @bevacqua
    ponyfoo.com
    Rest Parameters
    function () {
    var list = [].slice.call(arguments)
    }
    Never again .slice arguments

    View Slide

  52. ! @nzgb " @bevacqua
    ponyfoo.com
    Rest Parameters
    Use rest … instead
    function (…list) {
    }

    View Slide

  53. ! @nzgb " @bevacqua
    ponyfoo.com
    Rest Parameters
    Named parameters and the rest
    function () {
    var rest = [].slice.call(arguments)
    var y = rest.shift()
    var x = rest.shift()
    }

    View Slide

  54. ! @nzgb " @bevacqua
    ponyfoo.com
    Rest Parameters
    Effortless using …rest
    function (x, y, …rest) {
    }

    View Slide

  55. ! @nzgb " @bevacqua
    ponyfoo.com
    Rest Parameters
    Arrows require parenthesis for rest
    var sumAll = (…all) => all
    .reduce((x,y) => x+y)
    sumAll(1, 1, 2, 3, 5, 8)
    // <- 20

    View Slide

  56. Spread Operator
    ! @nzgb " @bevacqua
    ponyfoo.com

    View Slide

  57. ! @nzgb " @bevacqua
    ponyfoo.com
    Spread Operator
    Combining arrays before ES6
    [1].concat([2, 3]).concat(4)

    View Slide

  58. ! @nzgb " @bevacqua
    ponyfoo.com
    Spread Operator
    Spread makes it easier!
    [1, …[2, 3], 4, …more]

    View Slide

  59. ! @nzgb " @bevacqua
    ponyfoo.com
    Spread Operator
    Dynamic calls need .apply before ES6
    merge.apply(null, [
    'a', 'b', 'c'
    ])

    View Slide

  60. ! @nzgb " @bevacqua
    ponyfoo.com
    Spread Operator
    Avoid .apply, use spread instead
    merge(…[
    'a', 'b', 'c'
    ])

    View Slide

  61. ! @nzgb " @bevacqua
    ponyfoo.com
    Spread Operator
    new + apply in ES5 is …hard
    new (Date.bind.apply(Date, [
    null, 2015, 11, 7
    ]))

    View Slide

  62. ! @nzgb " @bevacqua
    ponyfoo.com
    Spread Operator
    new + apply in ES6 is …easy
    new Date(…[
    2015, 11, 7
    ])

    View Slide

  63. ! @nzgb " @bevacqua
    ponyfoo.com
    Spread Operator
    Separating array elements is
    tedious before ES6
    var all = [1, 2, 3, 4]
    var first = all[0]
    var rest = all.slice(1)

    View Slide

  64. ! @nzgb " @bevacqua
    ponyfoo.com
    Spread Operator
    Spread while destructuring!
    var all = [1, 2, 3, 4]
    var [first, …rest] = all

    View Slide

  65. ! @nzgb " @bevacqua
    ponyfoo.com
    Spread Operator
    Obnoxious casting before ES6
    var all = document.querySelectorAll('a')
    var links = [].slice.call(all)

    View Slide

  66. ! @nzgb " @bevacqua
    ponyfoo.com
    Spread Operator
    Iterables are easy to cast
    NodeList is iterable by default
    var all = document.querySelectorAll('a')
    var links = […all]

    View Slide

  67. ! @nzgb " @bevacqua
    ponyfoo.com
    Spread Operator
    Printing external links
    […document.querySelectorAll('a')]
    .map(a => a.href)
    .filter(href => !href
    .startsWith(location.origin))
    .forEach(href => console.log(href))

    View Slide

  68. ! @nzgb " @bevacqua
    ponyfoo.com
    Template Literals
    Strings, really.

    View Slide

  69. ! @nzgb " @bevacqua
    ponyfoo.com
    Template Literals
    Clunky concatenation before ES6
    'Hello, ' + name + '!'
    `Hello, ${name}!`
    Expression interpolation

    View Slide

  70. ! @nzgb " @bevacqua
    ponyfoo.com
    Template Literals
    [
    'Before ES6',
    'multiline strings',
    'were noisy'
    ].join('\n')
    Arrays, concatenation, escapes, even comments

    View Slide

  71. ! @nzgb " @bevacqua
    ponyfoo.com
    Template Literals
    `In ES6, just use
    template literals
    Multiline supported!`
    Multiline support built into template literals

    View Slide

  72. ! @nzgb " @bevacqua
    ponyfoo.com
    Tagged Templates

    View Slide

  73. ! @nzgb " @bevacqua
    ponyfoo.com
    Template Literals
    var tag = (parts, …model) =>
    parts.reduce(
    (all, part, i) =>
    all + model[i-1] + part
    )
    tag`Hello ${name}!`

    View Slide

  74. ! @nzgb " @bevacqua
    ponyfoo.com
    Template Literals
    var tag = (parts, …model) =>
    parts.reduce(
    (all, part, i) =>
    all + model[i-1] + part
    )
    tag`Hello ${name}!`

    View Slide

  75. ! @nzgb " @bevacqua
    ponyfoo.com
    Template Literals
    var tag = (parts, …model) =>
    parts.reduce(
    (all, part, i) =>
    all + model[i-1] + part
    )
    tag`Hello ${name}!`

    View Slide

  76. ! @nzgb " @bevacqua
    ponyfoo.com
    Template Literals
    var tag = (parts, …model) =>
    parts.reduce(
    (all, part, i) =>
    all + model[i-1] + part
    )
    tag`Hello ${name}!`

    View Slide

  77. ! @nzgb " @bevacqua
    ponyfoo.com
    Template Literals
    var tag = (parts, …model) =>
    parts.reduce(
    (all, part, i) =>
    all + model[i-1] + part
    )
    tag`Hello ${name}!`
    Strictly better than
    'single' or "double"
    quoted strings

    View Slide

  78. ! @nzgb " @bevacqua
    ponyfoo.com
    Let Variables

    View Slide

  79. ! @nzgb " @bevacqua
    ponyfoo.com
    Let, Const, and the “TDZ”
    function multiplySmall (input) {
    if (input < 10) {
    var mult = 2
    return mult * input
    }
    return input
    }
    var mult is function-scoped

    View Slide

  80. ! @nzgb " @bevacqua
    ponyfoo.com
    Let, Const, and the “TDZ”
    function multiplySmall (input) {
    if (input < 10) {
    let mult = 2
    return mult * input
    }
    return input
    }
    let mult is block-scoped

    View Slide

  81. function multiplySmall (input) {
    if (input < 10) {
    let mult = 2
    return mult * input
    }
    return input
    }
    let mult is hoisted to top of block
    ! @nzgb " @bevacqua
    ponyfoo.com
    Let, Const, and the “TDZ”

    View Slide

  82. ! @nzgb " @bevacqua
    ponyfoo.com
    “Temporal Dead” Zone

    View Slide

  83. TDZ for amount variable
    ! @nzgb " @bevacqua
    ponyfoo.com
    Let, Const, and the “TDZ”
    if (true) {
    // other
    // statements
    let amount = 2
    }
    [ Accessing
    amount
    within TDZ
    throws

    View Slide

  84. ! @nzgb " @bevacqua
    ponyfoo.com
    Constants

    View Slide

  85. const is like let, except:
    items must be initialized
    items is read-only
    items is not immutable
    ! @nzgb " @bevacqua
    ponyfoo.com
    Let, Const, and the “TDZ”
    const items = [1,2,3]
    items = [5]
    items.push(4)

    View Slide

  86. ! @nzgb " @bevacqua
    ponyfoo.com

    View Slide

  87. ! @nzgb " @bevacqua
    ponyfoo.com
    Iterators
    Generators
    Promises
    Built-ins
    Unicode
    Modules
    Proxies
    Reflection
    Map
    Set
    WeakMap
    WeakSet

    View Slide

  88. ! @nzgb " @bevacqua
    ponyfoo.com
    ponyfoo.com
    /articles/es6

    View Slide

  89. ! @nzgb " @bevacqua
    ponyfoo.com

    View Slide