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

ECMAScript 2017 and beyond

ECMAScript 2017 and beyond

In this talk, we’ll go into the latest JavaScript features and how they are designed.

Starting with ECMAScript 2016, the new “TC39 process” is used to create ECMAScript versions. We’ll start by learning how it works. Then we will take a look at the final feature set of ES2017, which was also created with that process and to which the last feature was aded at the end of January. Finally, we’ll examine what features are likely to be added to JavaScript after ES2017.

Axel Rauschmayer

February 19, 2017
Tweet

More Decks by Axel Rauschmayer

Other Decks in Programming

Transcript

  1. ECMAScript 2017 and beyond Axel Rauschmayer @rauschma The Rolling Scopes

    Conference Minsk, 19 February 2017 Slides: speakerdeck.com/rauschma
  2. Dr. Axel Rauschmayer @rauschma Overview • How is JavaScript evolved?

    • What are the features of ECMAScript 2016? • What are the features of ECMAScript 2017? • What’s in store for JS after ES2017? 2
  3. Dr. Axel Rauschmayer @rauschma JavaScript vs. ECMAScript • Meaning: •

    JavaScript: the language • ECMAScript: the standard for the language • ECMAScript 6 etc.: language versions • Ecma: standards organisation hosting ECMAScript 4
  4. Dr. Axel Rauschmayer @rauschma TC39 • Ecma Technical Committee 39

    (TC39): the committee evolving JavaScript • Members – strictly speaking: companies (all major browser vendors etc.) • Bi-monthly meetings of delegates and invited experts 5
  5. Dr. Axel Rauschmayer @rauschma Ecma Technical Committee 39 (TC39) github.com/hemanth/tc39-members

    { "members": { "Ordinary": [ "Adobe", "AMD", "eBay", "Google", "HewlettPackard", "Hitachi", "IBM", "Intel", "KonicaMinolta" ],
 "Associate": [ "Apple", "Canon", "Facebook", "Fujitsu", "JREastMechatronics", "Netflix", "NipponSignal", "NXP", "OMRONSocialSolutions", "Ricoh", "Sony", "Toshiba", "Twitter" ], ... 6
  6. Dr. Axel Rauschmayer @rauschma Timeline of ECMAScript • ECMAScript 1

    (June 1997): first version • ECMAScript 2 (June 1998): keep in sync with ISO standard • ECMAScript 3 (December 1999): many core features – “[…] regular expressions, better string handling, new control statements [do-while, switch], try/catch exception handling, […]” • ECMAScript 4 (abandoned in July 2008) • ECMAScript 5 (December 2009): minor improvements (standard library and strict mode) • ECMAScript 5.1 (June 2011): keep in sync with ISO standard • ECMAScript 6 (June 2015): many new features 7
  7. Dr. Axel Rauschmayer @rauschma The TC39 process Problems with infrequent,

    large releases (such as ES6): • Features that are ready sooner have to wait. • Features that are not ready are under pressure to get finished. • Next release would be a long time away. • They may delay the release. 8
  8. Dr. Axel Rauschmayer @rauschma The TC39 process New TC39 process:

    • Manage features individually (vs. one monolithic release). • Per feature: proposal that goes through maturity stages, numbered 0 (strawman) – 4 (finished). • Introduce features gradually. • Once a year, there is a new ECMAScript version. • Only features that are ready (=stage 4) are added. 9
  9. Dr. Axel Rauschmayer @rauschma Stage 0: strawman What is it?

    • First sketch • Submitted by TC39 member or
 registered TC39 contributor What’s required? • Review at TC39 meeting 10
  10. Dr. Axel Rauschmayer @rauschma Stage 1: proposal What is it?

    • Actual proposal of a feature • TC39 is willing to help with designing the feature What’s required? • Identify champion(s), one of them a TC39 member • Spec: prose, examples, API, semantics and algorithms • Implementation: polyfills and demos What’s next? • Major changes are still expected 11
  11. Dr. Axel Rauschmayer @rauschma Stage 2: draft What is it?

    • First version of what will be in the spec • Eventual standardisation is likely What’s required? • Formal description of syntax and semantics (gaps are OK) • Two experimental implementations (incl. one transpiler) What’s next? • Only incremental changes are expected 12
  12. Dr. Axel Rauschmayer @rauschma Stage 3: candidate What is it?

    • Proposal is mostly finished, now needs feedback from implementations What’s required? • Spec text is complete • Signed off by reviewers and ES spec editor • At least two spec-compliant implementations What’s next? • Changes only in response to critical issues. 13
  13. Dr. Axel Rauschmayer @rauschma Stage 4: finished What is it?

    • Proposal ready to be included in the ES specification What’s required? • Test 262 acceptance tests • Two spec-compliant shipping implementations that pass the tests • Significant practical experience with the implementations • ECMAScript spec editor must sign off on the spec text What’s next? • Proposal will be added to spec as soon as possible • When spec is next ratified, the proposal becomes a standard 14
  14. Dr. Axel Rauschmayer @rauschma Think in proposals & stages, not

    in ES versions • Before stage 4: proposals may be withdrawn. • Object.observe(): withdrawn at stage 2 • Stage 4: proposal will certainly become a part of ECMAScript. • But: don’t know when exactly. Tip: Ignore features before stage 3. 15
  15. Dr. Axel Rauschmayer @rauschma New features in ES2016 ES2016 has

    only two new features: • Array.prototype.includes (Domenic Denicola, Rick Waldron) • Exponentiation Operator (Rick Waldron) 17
  16. Dr. Axel Rauschmayer @rauschma Array.prototype.includes > ['a', 'b', 'c'].includes('a') true

    > ['a', 'b', 'c'].includes('d') false > [NaN].includes(NaN) true > [NaN].indexOf(NaN) >= 0 false 18
  17. Dr. Axel Rauschmayer @rauschma Exponentiation operator // x ** y

    is same as Math.pow(x, y) const squared = 3 ** 2; // 9 let num = 3; num **= 2; // same: num = num ** 2 console.log(num); // 9 19
  18. Dr. Axel Rauschmayer @rauschma Features of ES2017 Major new features:

    • Async Functions (Brian Terlson) • Shared memory and atomics (Lars T. Hansen) Minor new features: • Object.values/Object.entries (Jordan Harband) • String padding (Jordan Harband, Rick Waldron) • Object.getOwnPropertyDescriptors() (Jordan Harband, Andrea Giammarchi) • Trailing commas in function parameter lists and calls (Jeff Morrison) 21
  19. Dr. Axel Rauschmayer @rauschma Async Functions function fetchJsonViaPromises(url) { return

    fetch(url) // browser API, returns Promise .then(request => request.text()) // returns Promise .then(text => { return JSON.parse(text); }) .catch(error => { console.log(`ERROR: ${error.stack}`); }); } async function fetchJsonAsync(url) { try { const request = await fetch(url); const text = await request.text(); return JSON.parse(text); } catch (error) { console.log(`ERROR: ${error.stack}`); } } 22
  20. Dr. Axel Rauschmayer @rauschma Async Functions Variants: // Async function

    declaration async function foo() {} // Async function expression const foo = async function () {}; // Async arrow function const foo = async () => {}; // Async method definition (in classes, too) const obj = { async foo() {} }; 23
  21. Dr. Axel Rauschmayer @rauschma Fulfilling the Promise of an async

    function async function asyncFunc() { return 123; } asyncFunc() .then(x => console.log(x)); // 123 24
  22. Dr. Axel Rauschmayer @rauschma Rejecting the Promise of an async

    function async function asyncFunc() { throw new Error('Problem!'); } asyncFunc() .catch(err => console.log(err)); // Error: Problem! 25
  23. Dr. Axel Rauschmayer @rauschma Handling rejected Promises inside async functions

    async function asyncFunc() { try { await otherAsyncFunc(); } catch (err) { console.error(err); } } // Equivalent to: function asyncFunc() { return otherAsyncFunc() .catch(err => { console.error(err); }); } 26
  24. Dr. Axel Rauschmayer @rauschma Async functions and Node.js Node.js 7.2+:

    $ node --harmony_async_await > async function f() { return 123 } > f().then(x => console.log(x)) 123 27
  25. Dr. Axel Rauschmayer @rauschma History of concurrency in JavaScript •

    Single main thread + asynchronicity via callbacks • Web Workers • Originally: copy and send strings • Structured cloning: copy and send structured data • Transferables: move and send structured data • Failed experiment: PJS / River Trail • High-level support for data parallelism (map(), filter(), reduce()) 28
  26. Dr. Axel Rauschmayer @rauschma Shared Array Buffers New – Shared

    Array Buffers: • A primitive building block for higher-level concurrency abstractions • Share data between workers • Let’s you compile threaded C++ code to JavaScript 29
  27. Dr. Axel Rauschmayer @rauschma Creating and sending a Shared Array

    Buffer //----- main.js ----- const worker = new Worker('worker.js'); // To be shared const sharedBuffer = new SharedArrayBuffer( 10 * Int32Array.BYTES_PER_ELEMENT); // 10 elts // Share sharedBuffer with the worker worker.postMessage({sharedBuffer}); // clone // Local only const sharedArray = new Int32Array(sharedBuffer); 30
  28. Dr. Axel Rauschmayer @rauschma Receiving a Shared Array Buffer //-----

    worker.js ----- self.addEventListener('message', event => { const {sharedBuf} = event.data; const sharedArr = new Int32Array(sharedBuf); // ··· }); 31
  29. Dr. Axel Rauschmayer @rauschma Problem: compilers may rearrange reads //

    Source code while (sharedArray[0] === 1) ; // Rearranged by compiler let tmp = sharedArray[0]; while (tmp === 1) ; // runs never or forever 32
  30. Dr. Axel Rauschmayer @rauschma Problem: writes may be reordered //

    main.js sharedArray[1] = 11; sharedArray[2] = 22; // worker.js while (sharedArray[2] !== 22) ; console.log(sharedArray[1]); // 0 or 11 33
  31. Dr. Axel Rauschmayer @rauschma Solution: Atomics Atomics ensures: • Operations

    are non-interruptible (atomic) – think transactions in DBs • Order of writes and reads is fixed • No reads or writes get eliminated • Can be used to synchronise non-atomic reads and writes 34
  32. Dr. Axel Rauschmayer @rauschma Using Atomics // main.js Atomics.store(sharedArray, 0,

    2); // worker.js while (Atomics.load(sharedArray, 0) === 0) ; console.log(Atomics.load(sharedArray, 0)); // 2 35
  33. Dr. Axel Rauschmayer @rauschma Atomics Loading and storing: • Atomics.load(ta

    : TypedArray<T>, index) : T • Atomics.store(ta : TypedArray<T>, index, value : T) : T • Atomics.exchange(ta : TypedArray<T>, index, value : T) : T • Atomics.compareExchange(ta : TypedArray<T>, index, expectedValue, replacementValue) : T Waiting and waking: • Atomics.wait(ta: Int32Array, index, value, timeout=Number.POSITIVE_INFINITY) : ('not-equal' | 'ok' | 'timed-out') • Atomics.wake(ta : Int32Array, index, count) 36
  34. Dr. Axel Rauschmayer @rauschma Atomics Simple modifications of Typed Array

    elements (ta[index] op= value): • Atomics.add(ta : TypedArray<T>, index, value) : T • Atomics.sub(ta : TypedArray<T>, index, value) : T • Atomics.and(ta : TypedArray<T>, index, value) : T • Atomics.or(ta : TypedArray<T>, index, value) : T • Atomics.xor(ta : TypedArray<T>, index, value) : T 37
  35. Dr. Axel Rauschmayer @rauschma Object.entries() Object.entries() returns an Array of

    [key,value] pairs: > Object.entries({ one: 1, two: 2 }) [ [ 'one', 1 ], [ 'two', 2 ] ] 38
  36. Dr. Axel Rauschmayer @rauschma Object.entries() Easier to iterate over properties:

    const obj = { one: 1, two: 2 }; for (const [k, v] of Object.entries(obj)) { console.log(k, v); } // Output // "one" 1 // "two" 2 39
  37. Dr. Axel Rauschmayer @rauschma String padding > '1'.padStart(3, '0') '001'

    > 'x'.padStart(3) ' x' > '1'.padEnd(3, '0') '100' > 'x'.padEnd(3) 'x ' 41
  38. Dr. Axel Rauschmayer @rauschma String padding Use cases: • Displaying

    tabular data in a monospaced font. • Adding a count to a file name: 'file 001.txt' • Aligning console output: 'Test 001: ✓' • Printing hexadecimal or binary numbers that have a fixed number of digits: '0x00FF' 42
  39. Dr. Axel Rauschmayer @rauschma Object. getOwnPropertyDescriptors() const obj = {

    [Symbol('foo')]: 123, get bar() { return 'abc' }, }; console.log(Object.getOwnPropertyDescriptors(obj)); // Output: // { [Symbol('foo')]: // { value: 123, // writable: true, // enumerable: true, // configurable: true }, // bar: // { get: [Function: bar], // set: undefined, // enumerable: true, // configurable: true } } 43
  40. Dr. Axel Rauschmayer @rauschma Object. getOwnPropertyDescriptors() Object.assign() is limited: can’t

    copy getters and setters, etc. // Copying properties const target = {}; Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); // Cloning objects const clone = Object.create( Object.getPrototypeOf(orig), Object.getOwnPropertyDescriptors(orig)); 44
  41. Dr. Axel Rauschmayer @rauschma Trailing commas in function parameter lists

    and calls Trailing commas are legal in object and Array literals: const obj = { first: 'Jane', last: 'Doe', }; const arr = [ 'red', 'green', 'blue', ]; console.log(arr.length); // 3 45
  42. Dr. Axel Rauschmayer @rauschma Trailing commas in function parameter lists

    and calls Two benefits: • Rearranging items is simpler (no commas to add or remove) • Version control systems can track what really changed. Versus: // From: [ 'foo' ] // To: [ 'foo', 'bar' ] 46
  43. Dr. Axel Rauschmayer @rauschma Trailing commas in function parameter definitions

    and calls The proposal: function foo( param1, param2, ) {} foo( 'abc', 'def', ); 47
  44. Dr. Axel Rauschmayer @rauschma Stage 3 features Soon: • import()

    (Domenic Denicola) • Asynchronous Iteration (Domenic Denicola) • Rest/Spread Properties (Sebastian Markbage) • Lifting Template Literal Restriction (Tim Disney) • Function.prototype.toString revision (Michael Ficarra) Later: • global (Jordan Harband) • SIMD.JS – SIMD APIs (John McCutchan, Peter Jensen, Dan Gohman, Daniel Ehrenberg) 49
  45. Dr. Axel Rauschmayer @rauschma import() So far, ES6 modules can

    only be loaded statically (in a fixed manner, specified at compile time). Load modules dynamically: import('./dir/someModule.js') .then(someModule => someModule.foo()); An operator, but used like a function. 51
  46. Dr. Axel Rauschmayer @rauschma import() Use cases: • Code splitting:

    load parts of your program on demand. • Conditional loading of modules:
 if (cond) { import(···).then(···) } • Computed module specifiers:
 import('module'+count).then(···) 52
  47. Dr. Axel Rauschmayer @rauschma Rest operator for properties (destructuring) const

    obj = {foo: 1, bar: 2, baz: 3}; const {foo, ...rest} = obj; // Same as: // const foo = 1; // const rest = {bar: 2, baz: 3}; function f({param1, param2, ...rest}) { // rest console.log('All parameters: ', {param1, param2, ...rest}); // spread return param1 + param2; } 53
  48. Dr. Axel Rauschmayer @rauschma Spread operator for properties (object literals)

    > const obj = {foo: 1, bar: 2}; > {...obj, baz: 3} { foo: 1, bar: 2, baz: 3 } 54
  49. Dr. Axel Rauschmayer @rauschma Spread properties use cases // Cloning

    objects const clone1 = {...obj}; // Merging objects const merged = {...obj1, ...obj2}; // Filling in defaults const data = {...DEFAULTS, ...userData}; // Non-destructively updating property `foo` const obj = {foo: 'a', bar: 'b'}; const obj2 = {...obj, foo: 1}; // {foo: 1, bar: 'b'} 55
  50. Dr. Axel Rauschmayer @rauschma Function.prototype. toString revision Improved spec of

    toString() for functions: • Return source code whenever possible • Previously: optional • Otherwise: standardised placeholder • Previously: must cause SyntaxError (hard to guarantee!) 56
  51. Dr. Axel Rauschmayer @rauschma Template literal revision Syntax rules after

    backslash: • \u starts a Unicode escape, which must look like \u{1F4A4} or \u004B • \x starts a hex escape, which must look like \x4B. • \ plus digit starts an octal escape (such as \141). Octal escapes are forbidden in template literals and strict mode string literals. Illegal: latex`\unicode` windowsPath`C:\uuu\xxx\111` 57
  52. Dr. Axel Rauschmayer @rauschma Template literal revision function tagFunc(tmplObj, substs)

    { return { Cooked: tmplObj, Raw: tmplObj.raw, }; } tagFunc`\u{4B}`; // { Cooked: [ 'K' ], Raw: [ '\\u{4B}' ] } 58
  53. Dr. Axel Rauschmayer @rauschma Template literal revision Solution: tagFunc`\uu ${1}

    \xx` // { Cooked: [ undefined, undefined ], // Raw: [ '\\uu ', ' \\xx' ] } 59
  54. Dr. Axel Rauschmayer @rauschma Asynchronous iteration // Synchronous iteration: for

    (const l of readLinesSync(fileName)) { console.log(l); } Problem: readLinesSync() must be synchronous. 60
  55. Dr. Axel Rauschmayer @rauschma Asynchronous iteration // Asynchronous iteration: for

    await (const l of readLinesAsync(fileName)) { console.log(l); } Works inside: • Async functions • Async generators (new, part of proposal) 61
  56. Dr. Axel Rauschmayer @rauschma Asynchronous iteration async function f() {

    const aI = createAsyncIterable(['a', 'b']); for await (const x of aI) { console.log(x); } } // Output: // a // b 62
  57. Dr. Axel Rauschmayer @rauschma Asynchronous generators: await async function* id(asyncIterable)

    { for await (const elem of asyncIterable) { yield elem; } } 64
  58. Dr. Axel Rauschmayer @rauschma Asynchronous iteration interface AsyncIterable { [Symbol.asyncIterator]()

    : AsyncIterator; } interface AsyncIterator { next() : Promise<IteratorResult>; } interface IteratorResult { value: any; done: boolean; } 65
  59. Dr. Axel Rauschmayer @rauschma Asynchronous iteration Possible to simplify? •

    Keep iteration protocol • Keep for-await-of • Maybe: drop async generators • Language complexity: AG function declarations, AG function expressions, AG method definitions • Communicating sequential processes (CSP) may be a simpler solution: github.com/dvlsg/async-csp 66
  60. Dr. Axel Rauschmayer @rauschma global Accessing the global object: •

    Browsers (main thread): window • Browsers (main thread & workers): self • Node.js: global // In browsers console.log(global === window); // true 68
  61. SIMD: single instruction, multiple data Aw Bw Cw Ax Bx

    Cx + = Ay By Cy Az Bz Cz Aw Bw Cw + = Ax Bx Cx + = Ay By Cy + = Az Bz Cz + = SISD SIMD
  62. Dr. Axel Rauschmayer @rauschma SIMD.JS • SIMD.JS: SIMD support in

    JavaScript • Example target: Intel’s SSE (Streaming SIMD Extensions) • Speed-up: up to 4 times (sometimes even more) 70
  63. Dr. Axel Rauschmayer @rauschma SIMD.JS • Operands – vectors of

    booleans, ints, floats:
 Bool8x16, Float32x4, Uint32x4 • Operations, e.g.: SIMD.Float32x4.abs(v) SIMD.Float32x4.neg(v) SIMD.Float32x4.sqrt(v) SIMD.Float32x4.add(v, w) SIMD.Float32x4.mul(v, w) SIMD.Float32x4.equal(v, w) 71
  64. Dr. Axel Rauschmayer @rauschma SIMD.JS const a = SIMD.Float32x4(1.0, 2.0,

    3.0, 4.0); const b = SIMD.Float32x4(5.0, 6.0, 7.0, 8.0); const c = SIMD.Float32x4.add(a,b); 72
  65. Dr. Axel Rauschmayer @rauschma SIMD.JS: data types Always 128 bits:

    • Booleans: SIMD.Bool8x16, SIMD.Bool16x8, SIMD.Bool32x4, SIMD.Bool64x2 • Signed integers: SIMD.Int8x16, SIMD.Int16x8, SIMD.Int32x4 • Unsigned integers: SIMD.Uint8x16, SIMD.Uint16x8, SIMD.Uint32x4 • Floating point numbers: SIMD.Float32x4, SIMD.Float64x2 73
  66. Dr. Axel Rauschmayer @rauschma Farther future: big integers // Takes

    a BigInt as argument, returns a BigInt function nthPrime(nth) { function isPrime(p) { for (let i = 2n; i < p; i++) { if (p % i === 0n) return false; } return true; } for (let i = 2n; ; i++) { if (isPrime(i)) { if (--nth === 0n) return i; } } } 74
  67. Dr. Axel Rauschmayer @rauschma Big integers • Overloaded operators •

    No implicit conversions or mixed operands • Numbers and bigints are not subsets of each other (you always lose if you coerce) • Prepares for value types 75
  68. Dr. Axel Rauschmayer @rauschma BigInt: Staying in 64 bits const

    x = BigInt.asUintN(64, 1234n); const y = BigInt.asUintN(64, 5678n); const result = BigInt.asUintN(64, x*y); 76