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

Introduction to ES2016 & ES2017

Introduction to ES2016 & ES2017

Yasuharu.S

April 02, 2018
Tweet

More Decks by Yasuharu.S

Other Decks in Programming

Transcript

  1. Introduction
    to
    ES2016 & ES2017
    2018-03-31
    CAMPHOR-
    @sakay_y (Cybozu, Inc.)

    View Slide

  2. ES2016 & ES2017

    View Slide

  3. !!!Attention!!!

    View Slide

  4. Internet Explorer
    ࢖͍ͷਓ

    View Slide

  5. ͢΂ͯະରԠ

    View Slide

  6. ES2016

    View Slide

  7. ES2016
    • Array.prototype.includes
    • Exponentiation Operator

    View Slide

  8. Array.prototype.includes

    View Slide

  9. Array.prototype.includes
    • ഑ྻʹཁૉؚ͕·ΕΔ͔Ͳ͏͔͕൑ఆͰ͖Δ
    const array = ['a', 'b', 'c'];
    array.includes('a'); // true
    array.includes('c'); // true
    array.includes('d'); // false

    View Slide

  10. Array.prototype.includes
    • ॻ͖ํ͸͜͏มΘΔ
    var array = ['a', 'b', 'c'];
    // before ES2015
    if (array.indexOf('a') > -1) {
    console.log('a ༗ͬͨΑʂ');
    }
    // after ES2016
    if (array.includes('b')) {
    console.log('b ༗ͬͨΑʂ');
    }

    View Slide

  11. Array.prototype.includes
    • NaNͷѻ͍͚ͩɺؾΛ͚ͭΔ͜ͱʂ
    [NaN].indexOf(NaN) > -1 // false
    [NaN].includes(NaN) // true

    View Slide

  12. Array.prototype.includes
    • ଎͍͠ɺՄಡੑ΋ߴ͍ͷͰ࢖͍ͬͯ͜͏

    View Slide

  13. Exponentiation Operator

    View Slide

  14. Exponentiation Operator
    • ྦྷ৐ͷԋࢉࢠ͕૿͑ͨΑʂ
    2 ** 2 // 4
    2 ** 3 // 8
    // before ES2015
    Math.pow(2, 2)
    Math.pow(2, 3)

    View Slide

  15. ES2017

    View Slide

  16. ES2017
    • String.prototype.padStart, String.prototype.padEnd
    • Object.values, Object.entries
    • Object.getOwnPropertyDescriptors
    • Trailing commas in function parameter lists and calls
    • async function
    • Shared memory and atomics


    View Slide

  17. String.prototype.padStart,
    String.prototype.padEnd

    View Slide

  18. String.prototype.padStart,
    String.prototype.padEnd
    • paddingͰ͖Δ
    'abc'.padStart(10); // " abc"
    'abc'.padStart(10, "foo"); // "foofoofabc"
    'abc'.padStart(6,"123465"); // "123abc"
    'abc'.padStart(8, "0"); // "00000abc"
    'abc'.padStart(1); // "abc"
    'abc'.padEnd(10); // "abc "
    'abc'.padEnd(10, "foo"); // "abcfoofoof"
    ‘abc'.padEnd(6, "123465"); // "abc123"
    .%/XFCEPDTΑΓҾ༻

    View Slide

  19. String.prototype.padStart,
    String.prototype.padEnd
    • ར༻ྫ
    // before ES2016
    // 6ܻͷࣾһ൪߸ʹ͢Δ
    function createEmployeeNumber(number) {
    const numberLength = String(number).length;
    if (numberLength > 6) {
    throw new Error("6ܻ·ͰͩΑ");
    }
    const padString = "0".repeat(6 - numberLength);
    return padString + number;
    }

    View Slide

  20. String.prototype.padStart,
    String.prototype.padEnd
    • ར༻ྫ
    // 6ܻͷࣾһ൪߸ʹ͢Δ
    function createEmployeeNumber(number) {
    if (String(number).length > 6) {
    throw new Error("6ܻ·ͰͩΑ");
    }
    return String(number).padStart(6, "0");
    }

    View Slide

  21. Object.values,
    Object.entries

    View Slide

  22. Object.values
    • ObjectͷྻڍՄೳͳॴ༗ϓϩύςΟͷ஋Λؚ
    Ή഑ྻͰฦ͢
    • ॱ൪͸ for ... in … ϧʔϓͷ࣮ߦॱͱҰॹ
    const obj = {hoge: 'a', fuga: 'b', bar: 'c'}
    console.log(Object.values(obj))
    // ["a", "b", "c"]
    const obj = {2: 'a', 5: 'b', 0:'c'}
    console.log(Object.values(obj))
    // ['c', 'a', 'b']

    View Slide

  23. Object.values
    • ObjectҎ֎Λ౉ͨ࣌͠͸ɺObjectʹܕม׵͞
    Ε࣮ͯߦ͞ΕΔ
    Object.values([]) // []
    Object.values('abc') // ["a", "b", "c"]
    Object.values('cba') // ["c", "b", "a"]
    Object.values(['abc']) // ["abc"]
    Object.values(['a', 'b', 'c']) // ["a", "b", "c"]

    View Slide

  24. Object.values
    const obj = {hoge: 'a', fuga: 'b', bar: 'c'}
    // valueΛॻ͖ग़͢
    Object.values(obj).forEach(value => {
    console.log(value);
    });
    // before ES2016
    Object.keys(obj).forEach(key => {
    console.log(obj[key]);
    });

    View Slide

  25. Object.entries
    • Ҿ਺ʹ༩͑ͨΦϒδΣΫτ͕ॴ༗͢Δɺྻڍ
    ՄೳͳϓϩύςΟͷ૊ [key, value] ͷ഑ྻΛฦ
    ͢
    • ॱ൪͸ for ... in … ϧʔϓͷ࣮ߦॱͱҰॹ
    const obj = {hoge: 'a', fuga: 'b'};
    console.log(Object.entries(obj));
    // Array(2) [["hoge", "a"], ["fuga", "b"]]

    View Slide

  26. Object.entries
    • Object -> Mapͷม׵ʹศར
    const obj = {hoge: 'a', fuga: 'b'};
    const map = new Map(Object.entries(obj));
    console.log(map);
    // Map(2) {"hoge" => "a", "fuga" => “b"}
    // before ES2016
    const obj = {hoge: 'a', fuga: 'b'};
    const map = new Map();
    Object.keys(obj).forEach(key => {
    map.set(key, obj[key]);
    });
    console.log(map);
    // Map(2) {"hoge" => "a", "fuga" => "b"}

    View Slide

  27. Object.getOwnPropertyDescriptors

    View Slide

  28. Object.getOwnPropertyDescr
    iptors
    • ΦϒδΣΫτͷ͢΂ͯͷϓϩύςΟσΟεΫϦ
    ϓλΛؚΉΦϒδΣΫτΛฦ͢
    ଐੑ ҙຯ
    8SJUBCMF ஋Λॻ͖ࠐΈՄೳ͔
    &OVNFSBCMF ྻڍՄೳ͔ʢGPSJOͱ͔Ͱର৅ʹ͢Δ͔ʣ
    $POpHVSBCMF %FTDSJQUPSΛมߋՄೳ͔
    7BMVF ஋
    (FU (FUUFS
    4FU 4FUUFS

    View Slide

  29. Object.getOwnPropertyDescr
    iptors
    • ES2015ҎલͰ΋
    • Object.defineProperty Ͱઃఆ
    • Object.getOwnPropertyDescriptor Ͱऔಘ
    • ES2017Ͱɺෳ਺ܗ͕Ͱ͖͚ͨͩ

    View Slide

  30. Trailing commas in function
    parameter lists and calls

    View Slide

  31. Trailing commas in function
    parameter lists and calls
    • Ҿ਺Λෳ਺ߦͰॻ͍ͨͱ͖ʹɺ͍ΘΏΔέπ
    ΧϯϚΛڐ༰
    function hoge(
    param1,
    param2, // <-- OK
    ) {
    return null;
    }
    hoge(
    "foo",
    "bar", // <-- OK
    )

    View Slide

  32. async function

    View Slide

  33. async function
    • asyncؔ਺ͱͦͷपลͷߏจ
    • asyncؔ਺͕࣮ߦ͞ΕΔͱɺPromiseΦϒδΣ
    ΫτΛฦ͢

    View Slide

  34. async function
    // 2ඵޙʹxΛฦ͢
    function resolveAfter2Seconds(x) {
    return new Promise(resolve => {
    setTimeout(() => { resolve(x); }, 2000);
    });
    }
    async function add1(x) {
    const a = await resolveAfter2Seconds(20);
    const b = await resolveAfter2Seconds(30);
    return x + a + b;
    }
    async function add2(x) {
    const p_a = resolveAfter2Seconds(20);
    const p_b = resolveAfter2Seconds(30);
    return x + await p_a + await p_b;
    }

    View Slide

  35. async function
    add1(10).then(v => {
    console.log(v); // 4ඵޙʹ60Λදࣔ͢Δ
    });
    add2(10).then(v => {
    console.log(v); // 2ඵޙʹ60Λදࣔ͢Δ
    });

    View Slide

  36. async function
    • before ES2015
    function add1(x) {
    return resolveAfter2Seconds(20).then(a => {
    return resolveAfter2Seconds(a + 30).then(b => {
    return b + x;
    });
    });
    }
    function add2(x) {
    return Promise.all([
    resolveAfter2Seconds(20),
    resolveAfter2Seconds(30)
    ]).then(values => {
    return x + values[0] + values[1];
    });
    }

    View Slide

  37. await ࣜʹ͍ͭͯ
    • await͸async functionͷ࣮ߦΛҰ࣌ఀࢭͯ͠ɺpromiseͷղ
    ܾΛ଴ͭ
    • awaitͱͨ͠஋͕promiseͰ͸ͳ͍৔߹ɺ஋Λղܾ͞Εͨ
    promiseʹม׵ͯ͠ɺͦΕΛ଴ͭ
    • await͸asyncؔ਺ͷதͳΒɺPromise.Allͱ͔΋଴ͬͯ͘
    ΕΔɻ
    • awaitͷΤϥʔॲཧ͸try/catchͱawait/catch͕ར༻Ͱ͖Δɻ

    View Slide

  38. await ͷΤϥʔॲཧ
    function resolveAfter2Seconds(x) {
    if (!Number.isInteger(x)) {
    return Promise.reject('error!');
    }
    return new Promise(resolve => {
    setTimeout(() => { resolve(x); }, 2000);
    });
    }
    async function add(x) {
    try {
    const a = await resolveAfter2Seconds(20);
    const b = await resolveAfter2Seconds(x);
    return x + a + b;
    } catch (e) {
    return e;
    }
    }
    add('x').catch(e => { console.log(e); });
    // 2ඵޙʹ error!

    View Slide

  39. await ͷΤϥʔॲཧ
    function handleError(e) {
    console.log(e);
    return Promise.resolve(0);
    }
    async function add(x) {
    const a = await resolveAfter2Seconds(20).catch(handleError);
    const b = await resolveAfter2Seconds('x').catch(handleError);
    return x + a + b;
    }
    add(10)
    .then(v => { console.log(v); })
    .catch(e => { console.log(e); });
    // 2ඵޙʹ handleError಺Ͱ error! ͕දࣔ͞Εͯ
    // 30 ͕දࣔ͞ΕΔ

    View Slide

  40. Shared memory and atomics

    View Slide

  41. Shared memory and atomics
    • SharedArrayBuffer
    • Atomics
    • WorkerؒͰ஋Λڞ༗͢Δ͜ͱ͕Ͱ͖Δํ๏ͷҰͭ
    • ࠓ·Ͱ͸postMessageͰ஋Λ΍ΓͱΓ͍ͯͨ͠
    • ϚϧνεϨουͰॲཧΛ͢Δ৔߹ʹɺmessage͸஗
    ͘ɺεϨουؒͰσʔλΛίϐʔ͢Δखஈͱͯ͠໘౗

    View Slide

  42. // worker.js
    let sBuffer;
    let bufferView;
    self.addEventListener('message', (msg) => {
    sBuffer = msg.data; // SharedArrayBufferΛड͚औΔɻ
    bufferView = new Uint8Array(sBuffer); // ૢ࡞ͷͨΊͷϏϡʔΛੜ੒͢Δɻ
    console.log(bufferView);
    });
    // main.js
    const worker = new Worker('worker.js');
    // SharedArrayBufferΛ࡞੒͢Δɻ
    // SharedArrayBuffer͸ݻఆ௕ͷ഑ྻͰɺίϯετϥΫλʹ͸όΠτ௕Λࢦఆ͢Δɻ
    // ࠓճ͸1όΠτͷSharedArrayBufferΛ࡞੒͢Δɻ
    const sBuffer = new SharedArrayBuffer(1);
    // ૢ࡞ͷͨΊͷϏϡʔΛੜ੒͢Δɻࠓճ͸uint8ɻ
    const bufferView = new Uint8Array(sBuffer);
    bufferView[0] = 123; // ஋Λॻ͖ࠐΉɻ
    // SharedArrayBufferΛϝοηʔδͱͯ͠ૹ৴͢Δɻ
    worker.postMessage(sBuffer);
    Ҿ༻ɿ4VCUFSSBOFBO'MPXFSCMPH4IBSFE"SSBZ#V⒎FSͱ"UPNJDT"1*Λ༻͍ͯ8PSLFSؒͰσʔλΛڞ༗͢Δ

    View Slide

  43. Atomics
    • SharedArrayBufferΛεϨουηʔϑʹར༻͢
    ΔͨΊͷΞτϛοΫԋࢉΛఏڙ͢ΔΦϒδΣ
    Ϋτ
    const sBuffer = new SharedArrayBuffer(10);
    const bufferView = new Uint8Array(sBuffer);
    bufferView[0] = 1;
    bufferView[1] = 2;
    // Atomics APIΛར༻ͯ͠εϨουηʔϑͳૢ࡞Λߦ͏ɻ
    Atomics.add(bufferView, 0, 10); // 0൪໨ͷ஋ʹɺ஋10Λ଍͢ɻ
    console.log(Atomics.load(bufferView, 0)); // 11
    Ҿ༻ɿ4VCUFSSBOFBO'MPXFSCMPH4IBSFE"SSBZ#V⒎FSͱ"UPNJDT"1*Λ༻͍ͯ8PSLFSؒͰσʔλΛڞ༗͢Δ

    View Slide

  44. Shared memory and atomics
    • 2018೥3݄31೔ݱࡏɺSharedArrayBuffer͸࢖
    ͑ͳ͍
    • Spectre ରԠ

    View Slide

  45. Shared memory and atomics
    • SharedArrayBuffer͸ɺਫ਼౓ͷߴ͍λΠϚʔͱ
    ͯ͠αΠυνϟωϧ߈ܸʹར༻Ͱ͖ͯ͠·͏
    • https://security.stackexchange.com/
    questions/177033/how-can-
    sharedarraybuffer-be-used-for-timing-
    attacks

    View Slide

  46. Thanks!

    View Slide

  47. Appendix

    View Slide

  48. ୤ઢɿObjectΑΓMap
    • ObjectͷΩʔ͸StringsͱSymbols͚ͩ

    Map͸೚ҙͷ஋͕ΩʔʹͳΔ
    • Mapͷେ͖͞͸sizeͰ͙͢औΕΔ
    • Object͸ϓϩτλΠϓΛ࣋ͭ
    • Map͸Ωʔͷ࡟আ΍௥ՃͷύϑΥʔϚϯε͕ྑ͍
    MDN web docs: Map

    View Slide

  49. ୤ઢɿྻڍՄೳͱॴ༗ͱ͸ʁ
    • MDN web docs: Enumerability and
    ownership of properties
    • ίʔυͰද͢ͱɺ

    hasOwnProperty() === true &&
    propertyIsEnumerable() === true

    View Slide

  50. ྻڍՄೳ
    const obj = {'hoge': 'a'};
    // Object.definePropertyͰ௥Ճ͞ΕͨϓϩύςΟ͸
    // enumerable͕σϑΥϧτͰfalse
    Object.defineProperty(obj, 'fuga', {value: 'b'});
    console.log(Object.values(obj));
    // [‘a’]
    // ྻڍՄೳͳϓϩύςΟͷόϦϡʔͷΈ

    View Slide

  51. const obj = {2: 'a', 5: 'b', 0:'c'};
    const obj_chain = Object.create(obj);
    for (var property in obj_chain) {
    console.log(obj_chain[property]);
    }
    // c
    // b
    // a
    for (var value in Object.values(obj_chain)) {
    console.log(value);
    }
    // undefined
    // ॴ༗ͯ͠ͳ͍ϓϩύςΟͷόϦϡʔ͸ग़ͳ͍
    ॴ༗

    View Slide

  52. ୤ઢɿSpectre ʹ͍ͭͯ
    • ਤղͰΘ͔ΔSpectreͱMeltdown 

    by Satoru Takeuchi
    • SpectreBusters͋Δ͍͸Linuxʹ͓͚Δ
    Spectreରࡦ

    by Masami Hiramatsu

    View Slide