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.

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 } } }