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

TC39, ECMAScript, and the Future of JavaScript

TC39, ECMAScript, and the Future of JavaScript

We’ll start by glancing at the TC39 proposal revision process – how new features are proposed, how proposals move through revision stages, and why some make the cut while others don’t. Then we’ll have a look at a few proposals in the pipeline – like object spread, async iterators, async generators, and *import()*. Last, we’ll move to more exciting stuff – automated code style fixes, compile-time startup optimizations, and the future of writing JavaScript code.

Nicolás Bevacqua

June 24, 2017
Tweet

More Decks by Nicolás Bevacqua

Other Decks in Programming

Transcript

  1. TC39,
    ECMAScript,
    and the Future
    of JavaScript

    View Slide

  2. ponyfoo.com
    twitter.com/nzgb

    View Slide

  3. ponyfoo.com/books

    View Slide

  4. What’s
    TC39?

    View Slide

  5. isNaN(NaN) // true
    isNaN(“A”) // true
    “A” == NaN // false
    “A” === NaN // false
    NaN === NaN // false

    Solution:
    Number.isNaN(“A”) // false
    Number.isNaN(NaN) // true

    View Slide

  6. isNaN(NaN) // true
    isNaN(“A”) // true
    “A” == NaN // false
    “A” === NaN // false
    NaN === NaN // false

    Solution:
    Number.isNaN(“A”) // false
    Number.isNaN(NaN) // true

    View Slide

  7. isNaN(NaN) // true
    isNaN(“A”) // true
    “A” == NaN // false
    “A” === NaN // false
    NaN === NaN // false

    Solution:
    Number.isNaN(“A”) // false
    Number.isNaN(NaN) // true

    View Slide

  8. isNaN(NaN) // true
    isNaN(“A”) // true
    “A” == NaN // false
    “A” === NaN // false
    NaN === NaN // false

    Solution:
    Number.isNaN(“A”) // false
    Number.isNaN(NaN) // true

    View Slide

  9. +0 == -0 // true
    +0 === -0 // true
    1/+0 === 1/-0 // false

    View Slide

  10. Write valid
    JavaScript
    with only +!()[]
    jsfuck.com

    View Slide

  11. Specification
    Development
    Process

    View Slide

  12. Living
    Standard
    tc39.github.io/ecma262
    github.com/tc39/proposals

    View Slide

  13. Stage 0

    View Slide

  14. Stage 1

    View Slide

  15. Stage 2

    View Slide

  16. Stage 3

    View Slide

  17. Stage 4

    View Slide

  18. prop-tc39.now.sh

    View Slide

  19. Release
    Cadence

    View Slide

  20. Proposals

    View Slide

  21. Array#includes
    (Stage 4)
    [1,2].indexOf(2) !== -1 // true
    [1,2].indexOf(3) !== -1 // false
    [1,2].includes(2) // true
    [1,2].includes(3) // false

    View Slide

  22. Array#includes
    (Stage 4)
    [1,2].indexOf(2) !== -1 // true
    [1,2].indexOf(3) !== -1 // false
    [1,2].includes(2) // true
    [1,2].includes(3) // false

    View Slide

  23. Async Functions
    (Stage 4)
    fetch(‘/api/products’)
    .then(res => res.json())
    .then(data => {

    updateView(data)
    })
    .catch(err => {
    console.log(‘Update failed’, err)
    })

    View Slide

  24. Async Functions
    (Stage 4)
    fetch(‘/api/products’)
    .then(res => res.json())
    .then(data => {

    updateView(data)
    })
    .catch(err => {
    console.log(‘Update failed’, err)
    })

    View Slide

  25. Async Functions
    (Stage 4)
    fetch(‘/api/products’)
    .then(res => res.json())
    .then(data => {

    updateView(data)
    })
    .catch(err => {
    console.log(‘Update failed’, err)
    })

    View Slide

  26. Async Functions
    (Stage 4)
    fetch(‘/api/products’)
    .then(res => res.json())
    .then(data => {

    updateView(data)
    })
    .catch(err => {
    console.log(‘Update failed’, err)
    })

    View Slide

  27. Async Functions
    (Stage 4)
    await fetch(‘/api/products’)
    .then(res => res.json())
    .then(data => {

    updateView(data)
    })
    .catch(err => {
    console.log(‘Update failed’, err)
    })

    View Slide

  28. Async Functions
    (Stage 4)
    const res = await fetch(‘/api/products’)
    .then(res => res.json())
    .then(data => {

    updateView(data)
    })
    .catch(err => {
    console.log(‘Update failed’, err)
    })

    View Slide

  29. Async Functions
    (Stage 4)
    const res = await fetch(‘/api/products’)
    const data = await res.json()
    .then(data => {

    updateView(data)
    })
    .catch(err => {
    console.log(‘Update failed’, err)
    })

    View Slide

  30. Async Functions
    (Stage 4)
    const res = await fetch(‘/api/products’)
    const data = await res.json()

    updateView(data)
    .catch(err => {
    console.log(‘Update failed’, err)
    })

    View Slide

  31. Async Functions
    (Stage 4)
    try {
    const res = await fetch(‘/api/products’)
    const data = await res.json()

    updateView(data)
    } catch(err) {
    console.log(‘Update failed’, err)
    }

    View Slide

  32. Async Functions
    (Stage 4)
    async function main() {
    try {
    const res = await fetch(‘/api/products’)
    const data = await res.json()

    updateView(data)
    } catch(err) {
    console.log(‘Update failed’, err)
    }
    }

    View Slide

  33. Async Functions
    (Stage 4)
    (async () => {
    try {
    const res = await fetch(‘/api/products’)
    const data = await res.json()

    updateView(data)
    } catch(err) {
    console.log(‘Update failed’, err)
    }
    })()

    View Slide

  34. Async Functions
    (Stage 4)
    (async () => {
    try {
    const res = await fetch(‘/api/products’)
    const data = await res.json()

    updateView(data)
    } catch(err) {
    console.log(‘Update failed’, err)
    }
    })()
    await (2 + 3)

    View Slide

  35. Async Functions
    (Stage 4)
    (async () => {
    try {
    const res = await fetch(‘/api/products’)
    const data = await res.json()

    updateView(data)
    } catch(err) {
    console.log(‘Update failed’, err)
    }
    })()
    `Price: ${ await getPrice() }`

    View Slide

  36. Async Functions
    (Stage 4)
    (async () => {
    try {
    const res = await fetch(‘/api/products’)
    const data = await res.json()

    updateView(data)
    } catch(err) {
    console.log(‘Update failed’, err)
    }
    })()
    renderView(await getPrice())

    View Slide

  37. Async Functions
    (Stage 4)
    (async () => {
    try {
    const res = await fetch(‘/api/products’)
    const data = await res.json()

    updateView(data)
    } catch(err) {
    console.log(‘Update failed’, err)
    }
    })()
    2 * (await getPrice())

    View Slide

  38. Async Functions
    (Stage 4)
    const sleep = delay => new Promise(resolve =>
    setTimeout(resolve, delay)
    )
    const slowLog = async (...terms) => {
    await sleep(2000)
    console.log(...terms)
    }
    slowLog(‘Well that was underwhelming’)
    .then(() => console.log(‘Nailed it!’))
    .catch(reason => console.error(‘Failed’, reason))

    View Slide

  39. Async Iteration
    (Stage 3)
    const list = {
    [Symbol.iterator]() {
    let i = 0
    return {
    next: () => ({
    value: i++,
    done: i > 5
    })
    }
    }
    }
    [...list]
    // <- [0, 1, 2, 3, 4]
    Array.from(list)
    // <- [0, 1, 2, 3, 4]
    for (const i of list) {
    // <- 0, 1, 2, 3, 4
    }

    View Slide

  40. Async Iteration
    (Stage 3)
    const list = {
    [Symbol.iterator]() {
    let i = 0
    return {
    next: () => ({
    value: i++,
    done: i > 5
    })
    }
    }
    }
    [...list]
    // <- [0, 1, 2, 3, 4]
    Array.from(list)
    // <- [0, 1, 2, 3, 4]
    for (const i of list) {
    // <- 0, 1, 2, 3, 4
    }

    View Slide

  41. Async Iteration
    (Stage 3)
    const list = {
    [Symbol.iterator]() {
    let i = 0
    return {
    next: () => ({
    value: i++,
    done: i > 5
    })
    }
    }
    }
    [...list]
    // <- [0, 1, 2, 3, 4]
    Array.from(list)
    // <- [0, 1, 2, 3, 4]
    for (const i of list) {
    // <- 0, 1, 2, 3, 4
    }

    View Slide

  42. Async Iteration
    (Stage 3)
    const list = {
    [Symbol.asyncIterator]() {
    let i = 0
    return {
    next: () => Promise.resolve({
    value: i++,
    done: i > 5
    })
    }
    }
    }

    View Slide

  43. Async Iteration
    (Stage 3)
    const list = {
    [Symbol.asyncIterator]() {
    let i = 0
    return {
    next: () => Promise.resolve({
    value: i++,
    done: i > 5
    })
    }
    }
    }
    for await (const i of items) {
    // <- 0, 1, 2, 3, 4
    }

    View Slide

  44. Async Iteration
    (Stage 3)
    const list = {
    [Symbol.asyncIterator]() {
    let i = 0
    return {
    next: () => Promise.resolve({
    value: i++,
    done: i > 5
    })
    }
    }
    }
    async function readItems() {
    for await (const i of items) {
    // <- 0, 1, 2, 3, 4
    }
    }

    View Slide

  45. Async Iteration
    (Stage 3)
    async function* getProducts(categoryUrl) {
    const listReq = await fetch(categoryUrl)
    const list = await listReq.json()
    for (const product of list) {
    const productReq = await product.url
    const product = await productReq.json()
    yield product
    }
    }

    View Slide

  46. Async Iteration
    (Stage 3)
    async function* getProducts(categoryUrl) {
    const listReq = await fetch(categoryUrl)
    const list = await listReq.json()
    for (const product of list) {
    const productReq = await product.url
    const product = await productReq.json()
    yield product
    }
    }
    async function readProducts() {
    const g = getProducts(category)
    for await (const product of g) {
    // use product details
    }
    }

    View Slide

  47. Rest/Spread Properties
    (Stage 3)
    Object.assign(
    {},
    { a: "a" },
    { b: "b" },
    { a: "c" }
    )
    {
    ...{ a: "a" },
    ...{ b: "b" },
    ...{ a: "c" }
    }
    // <- { a: "c", b: "b"}

    View Slide

  48. Rest/Spread Properties
    (Stage 3)
    Object.assign(
    {},
    { a: "a" },
    { b: "b" },
    { a: "c" }
    )
    {
    ...{ a: "a" },
    ...{ b: "b" },
    ...{ a: "c" }
    }
    // <- { a: "c", b: "b"}

    View Slide

  49. Rest/Spread Properties
    (Stage 3)
    Object.assign(
    {},
    { a: "a" },
    { b: "b" },
    { a: "c" }
    )
    {
    ...{ a: "a" },
    ...{ b: "b" },
    ...{ a: "c" }
    }
    // <- { a: "c", b: "b"}

    View Slide

  50. Rest/Spread Properties
    (Stage 3)
    const item = {
    id: '4fe09c27',
    name: 'Banana',
    amount: 3
    }
    const { id, ...rest } = item
    // <- { name: 'Banana', amount: 3 }

    View Slide

  51. Rest/Spread Properties
    (Stage 3)
    function print({ id, ...rest }) {
    console.log(rest)
    }
    print({
    id: '4fe09c27', name: 'Banana'
    })
    // <- { name: 'Banana'}

    View Slide

  52. Dynamic import()
    (Stage 3)
    import markdown from './markdown'
    // ...
    export default compile

    View Slide

  53. Dynamic import()
    (Stage 3)
    import(`./i18n.${ navigator.language }.js`)
    .then(module => console.log(module.messages))
    .catch(reason => console.error(reason))

    View Slide

  54. Named Captures
    (Stage 3)
    const urlRegExp = /^(?:
    (http[s]?|ftp):\/)?\/?([^:\/
    \s]+)((?:\/\w+)*\/)([\w\-\.]+
    [^#?\s]+)([^#]*)?(#[\w\-]+)?$/

    View Slide

  55. Named Captures
    (Stage 3)
    const urlRegExp = /^(?:(?
    http[s]?|ftp):\/)?
    \/?(?[^:\/\s]+)(?
    (?:\/\w+)*\/)(?
    [\w\-\.]+[^#?\s]+)(?
    [^#]*)?(?#[\w\-]
    +)?$/u

    View Slide

  56. Named Captures
    (Stage 3)
    const urlRegExp = /^(?(?
    http[s]?|ftp):\/)?
    \/?(?[^:\/\s]+)(?
    (?:\/\w+)*\/)(?
    [\w\-\.]+[^#?\s]+)(?
    .*)?(?#[\w\-]+)?
    $/
    const url = 'https://commits.com/8b48e3/diff?w=1#readme'
    const { groups } = urlRegExp.exec(url)
    console.log(groups)
    {
    protocol: 'https',
    host: 'commits.com',
    path: '/8b48e3/',
    file: 'diff',
    query: '?w=1',
    hash: '#readme'
    }

    View Slide

  57. Named Captures
    (Stage 3)
    const urlRegExp = /^(?(?
    http[s]?|ftp):\/)?
    \/?(?[^:\/\s]+)(?
    (?:\/\w+)*\/)(?
    [\w\-\.]+[^#?\s]+)(?
    .*)?(?#[\w\-]+)?
    $/
    const url = 'https://commits.com/8b48e3/diff?w=1#readme'
    const pattern = '$://github.com/$'
    const replaced = url.replace(urlRegExp, pattern)
    console.log(replaced)
    // <- 'https://github.com/diff'

    View Slide

  58. Named Captures
    (Stage 3)
    const urlRegExp = /^(?(?
    http[s]?|ftp):\/)?
    \/?(?[^:\/\s]+)(?
    (?:\/\w+)*\/)(?
    [\w\-\.]+[^#?\s]+)(?
    .*)?(?#[\w\-]+)?
    $/
    const duplicateRegExp = /^(.*)=\1$/
    const duplicateRegExp = /^(?.*)=\k$/u
    duplicateRegExp.test('a=b') // <- false
    duplicateRegExp.test('a=a') // <- true
    duplicateRegExp.test('aa=a') // <- false
    duplicateRegExp.test('bbb=bbb') // <- true

    View Slide

  59. Unicode Escapes
    (Stage 3)
    /^\p{Script=Greek}$/u.test('π')
    // <- true
    /^\P{Script=Greek}$/u.test('π')
    // <- false

    View Slide

  60. Lookbehind Assertions
    (Stage 3)
    /\d+/.test('¥1245') // <- true
    /(?/(?

    View Slide

  61. Lookbehind Assertions
    (Stage 3)
    /\d+/.test('¥1245') // <- true
    /(?/(?/(?<=¥)\d+/.test('¥1245') // <- true
    /(?<=¥)\d+/.test('$1245') // <- false

    View Slide

  62. Class Decorators
    (Stage 2)
    @pure
    @decorators.elastic()
    class View {
    @throttle(200)
    reconcile() {
    }
    }

    View Slide

  63. Class Decorators
    (Stage 2)
    @pure
    @decorators.elastic()
    class View {
    @throttle(200)
    reconcile() {
    }
    }
    function readonly({ descriptor, ...rest }) {
    return {
    ...rest,
    descriptor: {
    ...descriptor,
    writable: false
    }
    }
    }

    View Slide

  64. Promise#finally
    (Stage 2)
    showSpinner()
    fetch(productUrl)
    .then(renderProduct)
    .then(
    hideSpinner,
    hideSpinner
    )

    View Slide

  65. Promise#finally
    (Stage 2)
    showSpinner()
    fetch(productUrl)
    .then(renderProduct)
    .finally(
    hideSpinner
    )

    View Slide

  66. Future of
    JavaScript

    View Slide

  67. View Slide

  68. View Slide

  69. View Slide

  70. View Slide

  71. View Slide

  72. View Slide

  73. View Slide

  74. View Slide

  75. View Slide

  76. View Slide

  77. Prepack

    View Slide

  78. Resources
    ponyfoo.com/articles/es6
    ponyfoo.com/articles/understanding-javascript-async-await
    ponyfoo.com/articles/regular-expressions-post-es6
    ponyfoo.com/articles/standard
    ponyfoo.com/articles/javascript-asynchronous-iteration-proposal
    ponyfoo.com/books/practical-modern-javascript/chapters
    prop-tc39.now.sh
    github.com/tc39/proposals
    twitter.com/nzgb

    View Slide
















































  79. Thanks!

    View Slide