Upgrade to Pro — share decks privately, control downloads, hide ads and more …

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.

Avatar for Nicolás Bevacqua

Nicolás Bevacqua

June 24, 2017
Tweet

More Decks by Nicolás Bevacqua

Other Decks in Programming

Transcript

  1. isNaN(NaN) // true isNaN(“A”) // true “A” == NaN //

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

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

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

    false “A” === NaN // false NaN === NaN // false … Solution: Number.isNaN(“A”) // false Number.isNaN(NaN) // true
  5. +0 == -0 // true +0 === -0 // true

    1/+0 === 1/-0 // false
  6. 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
  7. 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
  8. Async Functions (Stage 4) fetch(‘/api/products’) .then(res => res.json()) .then(data =>

    {
 updateView(data) }) .catch(err => { console.log(‘Update failed’, err) })
  9. Async Functions (Stage 4) fetch(‘/api/products’) .then(res => res.json()) .then(data =>

    {
 updateView(data) }) .catch(err => { console.log(‘Update failed’, err) })
  10. Async Functions (Stage 4) fetch(‘/api/products’) .then(res => res.json()) .then(data =>

    {
 updateView(data) }) .catch(err => { console.log(‘Update failed’, err) })
  11. Async Functions (Stage 4) fetch(‘/api/products’) .then(res => res.json()) .then(data =>

    {
 updateView(data) }) .catch(err => { console.log(‘Update failed’, err) })
  12. Async Functions (Stage 4) await fetch(‘/api/products’) .then(res => res.json()) .then(data

    => {
 updateView(data) }) .catch(err => { console.log(‘Update failed’, err) })
  13. 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) })
  14. 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) })
  15. Async Functions (Stage 4) const res = await fetch(‘/api/products’) const

    data = await res.json()
 updateView(data) .catch(err => { console.log(‘Update failed’, err) })
  16. 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) }
  17. 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) } }
  18. 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) } })()
  19. 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)
  20. 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() }`
  21. 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())
  22. 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())
  23. 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))
  24. 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 }
  25. 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 }
  26. 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 }
  27. Async Iteration (Stage 3) const list = { [Symbol.asyncIterator]() {

    let i = 0 return { next: () => Promise.resolve({ value: i++, done: i > 5 }) } } }
  28. 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 }
  29. 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 } }
  30. 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 } }
  31. 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 } }
  32. Rest/Spread Properties (Stage 3) Object.assign( {}, { a: "a" },

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

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

    { b: "b" }, { a: "c" } ) { ...{ a: "a" }, ...{ b: "b" }, ...{ a: "c" } } // <- { a: "c", b: "b"}
  35. Rest/Spread Properties (Stage 3) const item = { id: '4fe09c27',

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

    console.log(rest) } print({ id: '4fe09c27', name: 'Banana' }) // <- { name: 'Banana'}
  37. Named Captures (Stage 3) const urlRegExp = /^(?:(? <protocol>http[s]?|ftp):\/)? \/?(?<host>[^:\/\s]+)(?

    <path>(?:\/\w+)*\/)(? <file>[\w\-\.]+[^#?\s]+)(? <query>[^#]*)?(?<hash>#[\w\-] +)?$/u
  38. Named Captures (Stage 3) const urlRegExp = /^(?<url>(? <protocol>http[s]?|ftp):\/)? \/?(?<host>[^:\/\s]+)(?

    <path>(?:\/\w+)*\/)(? <file>[\w\-\.]+[^#?\s]+)(? <query>.*)?(?<hash>#[\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' }
  39. Named Captures (Stage 3) const urlRegExp = /^(?<url>(? <protocol>http[s]?|ftp):\/)? \/?(?<host>[^:\/\s]+)(?

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

    <path>(?:\/\w+)*\/)(? <file>[\w\-\.]+[^#?\s]+)(? <query>.*)?(?<hash>#[\w\-]+)? $/ const duplicateRegExp = /^(.*)=\1$/ const duplicateRegExp = /^(?<thing>.*)=\k<thing>$/u duplicateRegExp.test('a=b') // <- false duplicateRegExp.test('a=a') // <- true duplicateRegExp.test('aa=a') // <- false duplicateRegExp.test('bbb=bbb') // <- true
  41. Lookbehind Assertions (Stage 3) /\d+/.test('¥1245') // <- true /(?<!¥)\d+/.test('¥1245') //

    <- false /(?<!¥)\d+/.test('$1245') // <- true /(?<=¥)\d+/.test('¥1245') // <- true /(?<=¥)\d+/.test('$1245') // <- false
  42. Class Decorators (Stage 2) @pure @decorators.elastic() class View { @throttle(200)

    reconcile() { } } function readonly({ descriptor, ...rest }) { return { ...rest, descriptor: { ...descriptor, writable: false } } }