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

ES6 — Obviously.

Avatar for Milos Milos
October 11, 2016

ES6 — Obviously.

In this talk, we will dive deep into some of the (not so obvious) parts of JavaScript’s current standard — including asynchronous flows, collections, modularity, abstractions — and how to best leverage their capabilities. 👀🔥

Avatar for Milos

Milos

October 11, 2016
Tweet

Other Decks in Programming

Transcript

  1. About me. —Miloš Sutanovac —Developer, Lecturer, Speaker —Past: ASTRAL →

    astral.de —Now: norapay.com, Teaching, Consulting, Speaking —Modern Web, Languages, Curiosity —@mixn
  2. Real estate. —Land boom —Market price of real property increases

    —Until unsustainable —Declines in a bubble —Happens every x years
  3. Obviously. % —Fix JavaScript’s existing mistakes (ideally) —Keep JavaScript light

    —Improve ways for well–established patterns —Introduce new concepts
  4. const maskify = toMask => { const l = toMask.length;

    return '*'.repeat(l > 4 ? l - 4 : 0) + toMask.slice(-4); }; maskify('5490122213335467'); // '************5467' maskify('0897933189'); // '******3189' maskify('1234'); // '1234'
  5. const x = 23971431; console.log(`The square root of ${x} is

    ${Math.sqrt(x)}`); // 'The square root of 23971431 // is 4896.062805969711'
  6. function doubler (template, expression) { return template.reduce((before, after, i) =>

    { return before + expression + after + expression * 2; }); } doubler`Double of ${2} is `; // 'Double of 2 is 4' doubler`Das Doppelte von ${2} ist `; // 'Das Doppelte von 2 ist 4'
  7. Variables. —const is immutable —The value of const is mutable

    —Object.freeze() —Temporal Dead Zone —Single binding per iteration
  8. const arr = []; for ( var i = 0;

    i < 3; i++ ) { arr.push(() => i); } arr.map(x => x()); // [3, 3, 3]
  9. const arr = []; for ( let i = 0;

    i < 3; i++ ) { arr.push(() => i); } arr.map(x => x()); // [0, 1, 2]
  10. Destructuring. ⚒ —Construct data ✅ —const person = { first:

    'Jane', last: 'Doe' }; —Extract data ✅ —const firstName = person.first; —Destructure data ❌ —Same syntax for extracting, as for constructing
  11. const [{ prop: x = 'Hello' } = { prop:

    123 }] = [{}]; console.log(x); // 'Hello'
  12. const person = 'John'; const { [person]: j } =

    { John: { hairColor: 'brown', eyeColor: 'green', height: 180 } }; console.log(j.eyeColor); // 'green'
  13. Destructuring. ⚒ —Defaults ✅ —Multiple ✅ —Computed property keys ✅

    —Nested destructuring ✅ — Arbitrarily deeply ✅
  14. const obj = { one: [ { foo: 123, bar:

    456 } ], two: true }; const { one: [{foo: f}] } = obj; console.log(f); // 123
  15. Destructuring. ⚒ —Defaults ✅ —Multiple ✅ —Computed property keys ✅

    —Nested destructuring ✅ — Arbitrarily deeply ✅ —rest–Operator (…) ✅
  16. const [mango, strawberry, ...otherColors] = [ 'green', 'red', 'purple', 'blue',

    'yellow' ]; console.log(otherColors); // ['purple', 'blue', 'yellow']
  17. let person = {}, favHobby; [favHobby, ...person.hobbies] = [ 'Basketball',

    'Football', 'Skateboarding' ]; console.log(person); // { hobbies: ['Football', 'Skateboarding'] }
  18. Destructuring. ⚒ —Defaults ✅ —Multiple ✅ —Computed property keys ✅

    —Nested destructuring ✅ — Arbitrarily deeply ✅ —rest–Operator (…) ✅ —Wherever data is assigned ✅
  19. const eatFruit = ({ fruit = 'Air', taste = 'neutral'

    } = {}) => `${fruit} tastes ${taste}`; eatFruit({ fruit: 'Mango', taste: 'sweet' }); // 'Mango tastes sweet' eatFruit({ fruit: 'Lemon' }); // 'Lemon tastes neutral' eatFruit(); // 'Air tastes neutral'
  20. const verb = 'speak'; const person = { [verb] ()

    { return 'Speaking'; }, run () { } }; person.speak(); // 'Speaking'
  21. class Person { constructor ({ name, age, height }) {

    Object.assign(this, { name: name, age: age, height: height }); } } const john = new Person({ name: 'John', age: 32, height: 178 });
  22. class Person { constructor ({ name, age, height }) {

    Object.assign(this, { name: name, age: age, height: height }); } } const john = new Person({ name: 'John', age: 32, height: 178 });
  23. class Person { constructor ({ name, age, height }) {

    Object.assign(this, { name, age, height }); } } const john = new Person({ name: 'John', age: 32, height: 178 });
  24. Modules. —Best of all worlds —Compact —Single or multiple exports

    —Circular dependencies —Configurable Loader API —Synchronous or asynchronous —Static structure
  25. // calc.js export function add (x, y) { return x

    + y; } export function sub (x, y) { return x - y; } // main.js import { add, sub } from 'calc'; add(5, 5); // 10 sub(100-50)); // 50 // Optional import * as calc from 'calc'; calc.add(5, 5); // 10 calc.sub(100-50)); // 50
  26. // Default import foo from 'src/lib'; // Namespace import *

    as foo from 'src/lib'; // Named import { foo, bar as bizz } from 'src/lib'; // Empty import 'src/lib';
  27. // Default export default class {} // Named function* genFunc

    () {} class FooClass {} export { genFunc, FooClass as Foo }; // Re–Export // module2.js export { fizz as fizzy } from './module1';
  28. Modules. —Import styles —Export styles —Exported values can be anonymous

    —Are hoisted —foo(); import { foo } from 'foo'; // ✔ —Should still be on top
  29. function* lyrics () { console.log('Hello…'); yield; console.log('Is it me, you’re

    looking for?'); yield; console.log('I can see it in your eyes…'); yield; console.log('I can see it in your smile…'); } const lionel = lyrics(); // 'Hello…' lionel.next(); // 'Is it me, you’re looking for?' lionel.next(); // 'I can see it in your eyes…' lionel.next(); // 'I can see it in your smile…' lionel.next();
  30. function* even (until) { for ( let i = 0;

    i <= until; i += 2 ) { yield i; } } for ( const num of even(10) ) { console.log(num); // 0, 2, 4, 6, 8, 10 } const evenTilTwenty = [...even(20)]; console.log(evenTilTwenty); // [0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20] const [, two, four, , eight] = even(8); console.log(two, four, eight); // 2, 4, 8
  31. const answers = [ 'It is certain.', 'It is decidedly

    so.', 'Without a doubt.' ], coRoutine = genFunc => { const genObj = genFunc(); genObj.next(); return genObj; }, genie = function* () { while ( true ) { let question = yield `[GENIE]: ${answer()}`; console.log(`[ME]: ${question}`) } }, answer = () => answers[Math.floor(Math.random() * answers.length)]; let genieObj = coRoutine(genie); console.log(genieObj.next('Is ES6 cool?').value);
  32. const co = require('co'); function getFile (url) { return fetch(url).then(request

    => request.text()); } co(function* () { try { const [foo, bar] = yield Promise.all([ getFile('files/foo.txt'), getFile('files/bar.txt') ]); console.log(foo, bar); } catch (e) { console.log(e); } });
  33. Generators. —Pausable functions —Exited/Re–entered —Data producers —Manually, for…of, spread–Operator, Destructuring

    —Data consumers —Coroutines —Async flows —Callbacks ⇾ Promises ⇾ Generators (+ Promises) ⇾ async / await
  34. class Person { constructor ({ name = null, age =

    0 } = {}) { Object.assign(this, { name, age }); } } const jane = new Person({ name: 'Jane', age: 32 }); const john = new Person({ name: 'John', age: 35 }); const peopleHobbies = new Map([ [jane, 'Basketball'], [john, 'Football'] ]); console.log(peopleHobbies.get(jane)); // 'Basketball' console.log(peopleHobbies.get(john)); // 'Football'
  35. const nums = [23, 1, 15, 1, 100, 91, 15];

    // Array -> Set -> spread -> Array const unique = [...new Set(nums)]; unique; // [23, 1, 15, 100, 91]
  36. const a = new Set([1, 2, 3, 4]), b =

    new Set([4, 5, 6, 7, 1]); union = new Set([...a, ...b]); union; // Set {1, 2, 3, 4, 5, 6, 7}
  37. const a = new Set([1, 2, 3, 4]), b =

    new Set([4, 5, 6, 7, 1]); intersection = new Set([...a].filter(e => b.has(e))); intersection; // Set {1, 4}
  38. const a = new Set([1, 2, 3, 4]), b =

    new Set([4, 5, 6, 7, 1]); diff = new Set([...a].filter(e => !b.has(e))); diff; // Set {2, 3}
  39. const negativize = arr => new Proxy(arr, { get (target,

    prop) { const index = +prop; if (index < 0) { prop = (target.length + index).toString(); } return Reflect.get(target, prop); } }); let arr = ['Hi', 'World', 'what’s', 'going', 'on?']; arr[-1]; // undefined arr = negativize(arr); arr[-1]; // 'on?' arr[-2]; // 'going'
  40. “The global object Reflect implements all interceptable operations of the

    JavaScript meta object protocol as methods […] which helps with forwarding operations from the handler to the target.” —Axel Rauschmayer
  41. const person = { name: 'Jane', _password: '123password456' }; const

    protectPrivacy = (prop, trap) => { if (prop[0] === '_') { throw new Error(`Can’t ${trap} private property ${prop}`); } }; const handler = { get (target, prop, value) { protectPrivacy(prop, 'get'); return Reflect.get(target, prop); }, set (target, prop, value) { protectPrivacy(prop, 'set'); return Reflect.get(target, prop); } }; const proxy = new Proxy(person, handler); proxy.name; // 'Jane' proxy._password; // Error: Can’t get private property _password
  42. Obviously. 4 —Decrease of “reinventing the wheel” —lol jk —Focus

    on the core —Iteration ∞ —Great for the web
  43. “The ECMAScript standarization process will behave more like HTML and

    CSS ones, where new features are standarized as consensus is reached, rather than clean-cut – or “limited by” – by version numbers.” —Nicolás Bevacqua
  44. Obviously. 4 —Decrease of “reinventing the wheel” —lol jk —Focus

    on the core —Iteration ∞ —Great for the web —ECMAScript as a living standard