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

ES2015の現在とESNextの未来

 ES2015の現在とESNextの未来

HTML Party in 鹿児島
で発表した ES2015 の話です。

Yosuke Furukawa
PRO

June 11, 2016
Tweet

More Decks by Yosuke Furukawa

Other Decks in Programming

Transcript

  1. ES2015 ͷݱࡏͱ
    ESNext ͷະདྷ
    @yosuke_furukawa in HTML Party ͔͝Μ·

    View Slide

  2. Twitter: @yosuke_furukawa
    Github: yosuke-furukawa

    View Slide

  3. ࠷ۙ

    View Slide

  4. View Slide

  5. ࡱӨ͞Εͨসإ

    View Slide

  6. ࢠͲ΋͕ੜ·ΕͨͷͰجຊ΍ͬ
    ͯΔͷ͸
    ύύͱOSSίϛολʔ

    View Slide

  7. JavaScript

    View Slide

  8. View Slide

  9. View Slide

  10. View Slide

  11. JavaScript is the world’s
    most misunderstood
    Programming Language
    — Douglas Crockford

    View Slide

  12. JavaScript Trap Examples

    View Slide

  13. JavaScript Traps 1
    var test = 'global';
    function foo() {
    console.log(test); // global?? local??
    if (true) {
    var test = 'local';
    console.log(test); // global?? local??
    }
    }
    foo();

    View Slide

  14. JavaScript Traps 1
    var test = 'global';
    function foo() {
    console.log(test); // undefined
    if (true) {
    var test = 'local';
    console.log(test); // local
    }
    }
    foo();

    View Slide

  15. JavaScript Traps 1
    var test = 'global';
    function foo() {
    var test;
    console.log(test); // undefined
    if (true) {
    test = 'local';
    console.log(test); // local
    }
    }
    foo();
    ࣮ࡍͷ&OHJOFͷ
    ղऍ͸͜͏ͳΔ

    View Slide

  16. JavaScript Traps 1
    var test = 'global';
    function foo() {
    console.log(test); // global?? local??
    if (true) {
    var test = 'local';
    console.log(test); // global?? local??
    }
    }
    foo();
    ר্͖͛ࣄނ

    View Slide

  17. JavaScript Traps 2
    var Alice = function() {
    this.name = 'Alice';
    };
    Alice.prototype.printNameInteval = function() {
    console.log(this.name); // Alice?
    setInterval(function() {
    console.log(this.name); // Alice???
    }, 1000);
    };
    var alice = new Alice();
    alice.printNameInteval();

    View Slide

  18. JavaScript Traps 2
    var Alice = function() {
    this.name = 'Alice';
    };
    Alice.prototype.printNameInteval = function() {
    console.log(this.name); // Alice
    setInterval(function() {
    console.log(this.name); // undefined
    }, 1000);
    };
    var alice = new Alice();
    alice.printNameTick();

    View Slide

  19. JavaScript Traps 2
    var Alice = function() {
    this.name = 'Alice';
    };
    Alice.prototype.printNameTick = function() {
    console.log(this.name); // this => Alice
    setInterval(function() {
    console.log(this.name); // this => ????? (browser͸window, node
    ͸ Timer
    }, 1000);
    };
    var alice = new Alice();
    alice.printNameTick();
    UIJT͕ࢦ͍ͯ͠Δ΋ͷ͕
    มΘΔ

    View Slide

  20. JavaScript Traps 2
    var Alice = function() {
    this.name = 'Alice';
    };
    Alice.prototype.printNameTick = function() {
    console.log(this.name); // Alice
    setInterval(function() {
    console.log(this.name); // undefined
    }, 1000);
    };
    var alice = new Alice();
    alice.printNameTick();
    ϰΝχογϡUIJT

    View Slide

  21. JavaScript Traps 3
    var fs = require('fs');
    var getLastModified = function(dir, done) {
    fs.readdir(function(err, files) {
    var timestamps = [];
    files.forEach(function(file) {
    fs.stat(file, function(err, stat) {
    timestamps.push(stat.mtime);
    if (timestamps.length === files.length) {
    done(null, timestamps);
    }
    });
    });
    });
    };
    getLastModified('.', function(err, results) {
    console.log(results);
    });

    View Slide

  22. JavaScript Traps 3
    var fs = require('fs');
    var getLastModified = function(dir, done) {
    fs.readdir(function(err, files) {
    var timestamps = [];
    files.forEach(function(file) {
    fs.stat(file, function(err, stat) {
    timestamps.push(stat.mtime);
    if (timestamps.length === files.length) {
    done(null, timestamps);
    }
    });
    });
    });
    };
    getLastModified('trap3.js', function(err, results) {
    console.log(results);
    });
    DBMMCBDLIFMM

    View Slide

  23. View Slide

  24. ES2015

    View Slide

  25. ES2015ʁ
    • JavaScript ͷ৽͍͠ *ن֨*
    • ਖ਼໊ࣜশ͸ ECMA-262
    • ௨শ ECMAScript
    • ECMA International ஂମ͕ఆٛ
    • ͋͘·Ͱن֨Ͱ࣮͋ͬͯ૷Ͱ͸ͳ͍

    View Slide

  26. ES6? ES7?
    • ECMA-262(௨শ ECMAScript) 6th Edition ͳ
    ͷͰ ES6
    • ࠓ೥͸ ES7
    • ͨͩ΋͏͜ͷݺশ͸ͦΜͳසൟʹ࢖Θͳ͍
    • ৄ͘͠͸ޙͰઆ໌͢Δ

    View Slide

  27. ES2015 ͸͖ͬ͞ͷ᠘Λճආ
    ͢ΔͨΊͷ๷۩

    View Slide

  28. avoid traps using ES2015

    View Slide

  29. JavaScript Traps 1
    var test = 'global';
    function foo() {
    console.log(test); // global?? local??
    if (true) {
    var test = 'local';
    console.log(test); // global?? local??
    }
    }
    foo();
    ר্͖͛ࣄނ

    View Slide

  30. Use let or const

    View Slide

  31. JavaScript Traps 1
    const test = 'global';
    function foo() {
    console.log(test); // global
    if (true) {
    const test = 'local';
    console.log(test); // local
    }
    }
    foo();

    View Slide

  32. JavaScript Traps 1
    const test = 'global';
    function foo() {
    console.log(test); // global
    if (true) {
    const test = 'local';
    console.log(test); // local
    }
    }
    foo();
    LGTM

    View Slide

  33. let ͱ const
    • block scope ͱݴͬͯม਺είʔϓ͕ϒϨʔε{}ͷதʹ
    ด͡Δ
    • let ͸࠶୅ೖՄೳͳม਺
    • const ͸࠶୅ೖෆՄೳͳม਺
    • جຊతʹ͸ const Λ࢖ͬͯ let ͸୅ೖՄೳͳ΋ͷʹͷ
    Έ࢖͏ͷ͕ίʔυϚφʔʹͳΓͭͭ͋Δ

    View Slide

  34. JavaScript Traps 2
    var Alice = function() {
    this.name = 'Alice';
    };
    Alice.prototype.printNameTick = function() {
    console.log(this.name); // Alice
    setInterval(function() {
    console.log(this.name); // undefined
    }, 1000);
    };
    var alice = new Alice();
    alice.printNameTick();
    ϰΝχογϡUIJT

    View Slide

  35. Use arrow function

    View Slide

  36. JavaScript Traps 2
    var Alice = function() {
    this.name = 'Alice';
    };
    Alice.prototype.printNameTick = function() {
    console.log(this.name); // Alice
    setInterval(() => {
    console.log(this.name); // Alice
    }, 1000);
    };
    var alice = new Alice();
    alice.printNameTick();

    View Slide

  37. JavaScript Traps 2
    var Alice = function() {
    this.name = 'Alice';
    };
    Alice.prototype.printNameTick = function() {
    console.log(this.name); // Alice
    setInterval(() => {
    console.log(this.name); // Alice
    }, 1000);
    };
    var alice = new Alice();
    alice.printNameTick();
    LGTM

    View Slide

  38. arrow function
    • Ξϩʔؔ਺ͱݴͬͯ this ͕Ξϩʔؔ਺಺ʹଋ
    റ͞ΕΔ
    • ؔ਺ͷதͰthisΛ࢖͏࣌ʹ͍͍ͪͪbind͢Δඞ
    ཁ͕ͳ͍ɻ
    // ͜͏͍͏࣌ʹ΋࢖͏ɻ
    [1,2,3,4,5,6,7,8,9].filter(n => n % 2 === 0).reduce(prev, curr => prev + curr);

    View Slide

  39. ͍ͭͰʹ֮͑Α͏
    class

    View Slide

  40. class
    class Alice {
    constructor() {
    this.name = 'Alice';
    }
    printNameTick() {
    console.log(this.name); // Alice
    setInterval(() => {
    console.log(this.name); // Alice
    }, 1000);
    }
    }
    var alice = new Alice();
    alice.printNameTick();
    LVGTM

    View Slide

  41. class
    • JavaScript Ͱ class Λ࡞ΕΔΑ͏ʹͳͬͨ
    • ͜Ε·Ͱͷ prototype ͷԆ௕
    • ܧঝͱ͔΋Մೳ
    class Alice extends Person {
    }

    View Slide

  42. JavaScript Traps 3
    var fs = require('fs');
    var getLastModified = function(dir, done) {
    fs.readdir(function(err, files) {
    var timestamps = [];
    files.forEach(function(file) {
    fs.stat(file, function(err, stat) {
    timestamps.push(stat.mtime);
    if (timestamps.length === files.length) {
    done(null, timestamps);
    }
    });
    });
    });
    };
    getLastModified('trap3.js', function(err, results) {
    console.log(results);
    });
    DBMMCBDLIFMM

    View Slide

  43. Use Promise

    View Slide

  44. JavaScript Traps 3
    const fs = require('fs');
    const promisify = require('./promisify');
    const readdir = promisify(fs.readdir);
    const stat = promisify(fs.stat);
    const getLastModified = (dir) => {
    return readdir(dir).then((files) => {
    const results = files.map((file) => stat(file));
    return Promise.all(results);
    }).then((stats) => stats.map(stat => stat.mtime));
    };
    getLastModified('.').then(results => {
    console.log(results);
    });

    View Slide

  45. JavaScript Traps 3
    const fs = require('fs');
    const promisify = require('./promisify');
    const readdir = promisify(fs.readdir);
    const stat = promisify(fs.stat);
    const getLastModified = (dir) => {
    return readdir(dir).then((files) => {
    const results = files.map((file) => stat(file));
    return Promise.all(results);
    }).then((stats) => stats.map(stat => stat.mtime));
    };
    getLastModified('.').then(results => {
    console.log(results);
    });
    LGTM

    View Slide

  46. Promise
    • ඇಉظॲཧͷݺͼग़͠Λந৅Խͨ͠΋ͷ
    • then Ͱ੒ޭ࣌ͷݺͼग़͠ɺ catch Ͱࣦഊ࣌ͷྫ֎͕औ
    ಘͰ͖Δ
    • then Ͱܨ͙͜ͱͰ callback hell Λճආ͢Δ
    • ※NodeͷAPI͸·ͩPromiseʹͳͬͯͳ͍ͷͰผ్
    PromiseԽ͢Δॲཧ(Promisify) ͕ඞཁ

    View Slide

  47. ͍ͭͰʹ֮͑Α͏
    generator/yield

    View Slide

  48. JavaScript Traps 3
    const co = require('co');
    const fs = require('fs');
    const promisify = require('./promisify');
    const readdir = promisify(fs.readdir);
    const stat = promisify(fs.stat);
    const getLastModified = (dir) => co(function* () {
    const files = yield readdir(dir);
    const stats = yield files.map((file) => stat(file));
    const mtimes = yield stats.map((stat) => stat.mtime);
    return mtimes;
    });
    getLastModified('.').then(results => {
    console.log(results);
    });
    LGTM

    View Slide

  49. generator/yield
    • ܁Γฦ͠ՄೳͳΦϒδΣΫτΛ࡞੒͢Δ
    generator ͱ܁Γฦ͠Λؔ਺ͷ్தͰࢭΊΔ
    yield ͷ૊Έ߹ΘͤͰඇಉظݺͼग़͠Ͱ΋ಉ
    ظͬΆ͘ॻ͚Δ
    • ※ͨͩ͠ɺcoͳͲͷwrapper͕ඞཁ

    View Slide

  50. ଞʹ΋ศརͳػೳ͸৭ʑ͋Δ
    spread/rest
    Proxy/Reflect
    Symbols
    modules
    template string literals

    View Slide

  51. ࠓ࢖͑Δͷʁʁʁ

    View Slide

  52. Yes and No

    View Slide

  53. Node.js v6 ͳΒ΄΅࢖͑Δ

    View Slide

  54. Browser͸ IE ͱ͔ແࢹͯ͠Α͚
    Ε͹࢖͑Δ

    View Slide

  55. Ͱ΋ɾɾɾ
    • ϒϥ΢β͝ͱʹ࢖͑Δػೳ͕όϥόϥ
    • Node.js ΋όʔδϣϯʹΑͬͯ͸࢖͑ͳ͔ͬͨ
    Γ΋͢Δ
    • ಛʹ ES Modules ͸EdgeҎ֎ͩͱ࢖͑ͳ͍
    • transpiler Λ࢖͏ͱIEͱ͔Ͱ΋ಈ͘Α͏ʹͳΔ

    View Slide

  56. Transpiler

    View Slide

  57. Transpiler
    • ES2015 Ͱॻ͍ͨΒม׵ͯ͠ݹ͍ϒϥ΢βͰ΋
    ࢖͑ΔΑ͏ʹͯ͘͠ΕΔػೳ

    View Slide

  58. transpiler Ͱ ES2015 ΍ͬͯ
    Έͨ͘ͳͬͨΒ

    View Slide

  59. tower-of-babel

    View Slide

  60. ESNext

    View Slide

  61. ES2016 (ES7) ͰೖΔ͜ͱ͕ܾ
    ·ͬͯΔ΋ͷ
    • ES2016
    • ΂͖৐ԋࢉࢠ 2 ** 3
    • Array.prototype.include

    View Slide

  62. ES2016 ͰೖΔ͜ͱ͕ܾ·ͬͯ
    Δ΋ͷ
    • ES2016
    • ΂͖৐ԋࢉࢠ 2 ** 3
    • Array.prototype.include
    ͑ͬͦΕ͚ͩʁʁʁ

    View Slide

  63. ͳΜ͔৭ʑES2015͸ͨ͘͞Μ
    ػೳ͋ͬͨͷʹɾɾɾ
    • جຊతʹ ECMAScript ͸೥࣍Ͱߋ৽͞ΕΔΑ
    ͏ʹͳͬͨ
    • ͦͷஈ֊Ͱٞ࿦͕ऴΘͬͯ࢓༷ʹೖΔࣄ͕֬
    ఆͨ͠ػೳ͕ͦͷ·· ECMAScript ͷ࣍ͷ೥
    ࣍ʹ௥Ճ͞ΕΔɻ

    View Slide

  64. feature based release
    • Web ͷਐԽ͸଎͍
    • ES2015͸࢓༷ࡦఆ·ͰʹԿ೥΋͔͔͍ͬͯΔ
    • ਐԽʹద༻͢ΔͨΊʹ೥࣍Ͱߋ৽
    • ػೳϕʔεͰܾ·͍ͬͯ͘

    View Slide

  65. ESNextظ଴ageͷػೳୡ

    View Slide

  66. async-await

    View Slide

  67. JavaScript Traps 3
    const co = require('co');
    const fs = require('fs');
    const promisify = require('./promisify');
    const readdir = promisify(fs.readdir);
    const stat = promisify(fs.stat);
    const getLastModified = (dir) => co(function* () {
    const files = yield readdir(dir);
    const stats = yield files.map((file) => stat(file));
    const mtimes = yield stats.map((stat) => stat.mtime);
    return mtimes;
    });
    getLastModified('.').then(results => {
    console.log(results);
    });

    View Slide

  68. JavaScript Traps 3
    const co = require('co');
    const fs = require('fs');
    const promisify = require('./promisify');
    const readdir = promisify(fs.readdir);
    const stat = promisify(fs.stat);
    const getLastModified = (dir) => co(function* () {
    const files = yield readdir(dir);
    const stats = yield files.map((file) => stat(file));
    const mtimes = yield stats.map((stat) => stat.mtime);
    return mtimes;
    });
    getLastModified('.').then(results => {
    console.log(results);
    }); ·ͩͪΐͬͱඍົ
    ओʹ͜ͷล

    View Slide

  69. JavaScript Traps 3
    const fs = require('fs');
    const promisify = require('./promisify');
    const readdir = promisify(fs.readdir);
    const stat = promisify(fs.stat);
    const getLastModified = (dir) => async function () {
    const files = await readdir(dir);
    const stats = await files.map((file) => stat(file));
    const mtimes = await stats.map((stat) => stat.mtime);
    return mtimes;
    });
    getLastModified('.').then(results => {
    console.log(results);
    });

    View Slide

  70. JavaScript Traps 3
    const fs = require('fs');
    const promisify = require('./promisify');
    const readdir = promisify(fs.readdir);
    const stat = promisify(fs.stat);
    const getLastModified = (dir) => async function () {
    const files = await readdir(dir);
    const stats = await files.map((file) => stat(file));
    const mtimes = await stats.map((stat) => stat.mtime);
    return mtimes;
    });
    getLastModified('.').then(results => {
    console.log(results);
    });
    LVGTM

    View Slide

  71. async-await
    • generator/yield Ͱ΍Δͷ͸एׯϋοΩʔ
    • generator/yield ͸܁Γฦ͠ՄೳͳΦϒδΣΫτͷੜ
    ੒ͱૢ࡞ʹಛԽͤͯ͞ɺඇಉظॲཧ͸ઐ༻ͷߏจΛ༻
    ҙ͢Δ
    • async-await Ͱॻ͘ͱ*/yield ΑΓ͸ݟ௨͕͠ྑ͍
    • དྷ೥ͷ ES2017 Ͱ͸ೖΔՄೳੑ͕ߴ͍

    View Slide

  72. SIMD

    View Slide

  73. SIMD
    const a = [1.0, 2.0, 3.0, 4.0];
    const b = [5.0, 6.0, 7.0, 8.0];
    const c = [];
    for(var i=0; ic[i] = a[i] + b[i];
    }
    console.log(c); // 6, 8, 10, 12

    View Slide

  74. SIMD
    var a = SIMD.float32x4(1.0, 2.0, 3.0, 4.0);
    var b = SIMD.float32x4(5.0, 6.0, 7.0, 8.0);
    var c = SIMD.float32x4.add(a,b);
    console.log(c); // 6, 8, 10, 12

    Faster!

    View Slide

  75. SIMD
    • JavaScript ͰϕΫτϧܭࢉΛ؆୯͔ͭߴ଎ʹ
    ߦΘͤΔΑ͏ʹ͢ΔͨΊͷ΋ͷ
    • Ԡ༻ྫɿػցֶशɺը૾ॲཧɺ෺ཧԋࢉɺ3D
    άϥϑΟοΫε etc
    • ES2017 ͰೖΔ͔΋ɾɾɾ

    View Slide

  76. class props declarations

    View Slide

  77. ES2015 class ͷදݱྗ͸௿͍
    class Alice {
    constructor() {
    this.name = 'Alice'
    }
    printNameTick() {
    console.log(this.name); // Alice
    setInterval(() => {
    console.log(this.name); // Alice
    }, 1000);
    }
    }
    var alice = new Alice();
    alice.printNameTick();
    member field ͸
    constructor ʹهड़
    ͠ͳ͍ͱ͍͚ͳ͍

    View Slide

  78. class props declarations
    class Alice {
    name = 'Alice'; // member field
    static foo = 'foo'; // static ͳfield΋ఆٛͰ͖Δ
    printNameTick() {
    console.log(this.name); // Alice
    setInterval(() => {
    console.log(this.name); // Alice
    }, 1000);
    }
    }
    var alice = new Alice();
    alice.printNameTick();

    View Slide

  79. class props declarations
    class Alice {
    name = 'Alice'; // member field
    static foo = 'foo'; // static ͳfield΋ఆٛͰ͖Δ
    printNameTick() {
    console.log(this.name); // Alice
    setInterval(() => {
    console.log(this.name); // Alice
    }, 1000);
    }
    }
    var alice = new Alice();
    alice.printNameTick();
    LVGTM

    View Slide

  80. class props declarations
    • class Ͱ௚઀member/static member Λॻ͚Δ
    Α͏ʹ͠Α͏ͱ͍͏΋ͷɻ
    • ಛʹ static member ͸ React ͱ͔Ͱ΋Α͘ར
    ༻͢ΔͷͰॻ͚Δͱخ͍͠ɻ
    • ͍ͭೖΔ͔͸ෆ໌ɺೖΒͳ͍Մೳੑ΋͋Δɻ

    View Slide

  81. ͍ͭͰʹ֮͑Α͏ private field

    View Slide

  82. private member field
    class Alice {
    #name = 'Alice'; // private member field
    printNameTick() {
    console.log(this.#name); // Alice
    setInterval(() => {
    console.log(this.#name); // Alice
    }, 1000);
    }
    }
    var alice = new Alice();
    alice.printNameTick();
    ‧‪‬‭⛺è('ω')è⛺䡡‬‪‧

    View Slide

  83. private member field
    • classʹ private memberΛॻ͚ΔΑ͏ʹ͠Α͏
    • #foo ͱ͔Ͱఆٛ
    • ͍ͭೖΔ͔͸ෆ໌ɺೖΒͳ͍Մೳੑ΋͋Δɻ

    View Slide

  84. ͍ͭͰʹ֮͑Α͏ Decorator

    View Slide

  85. Decorator
    class Alice {
    #firstname = 'Alice'; // private member field
    #lastname = 'Bob'; // private member field
    @readonly // decorator
    fullname() { return `${this.#firstname} ${this.#lastname}` }
    }
    var alice = new Alice();
    console.log(alice.fullname());
    alice.fullname = function someMock(){}; // error

    View Slide

  86. Decorator
    • class/function/member ʹରͯͦ͠ΕΛ೚ҙͷ
    ػೳͰम০(decorate)ͤ͞Δ
    • @readonlyͱ͔@nonenumerableͱ͔
    @overrideͱ͔෇͚ΒΕΔ
    • ͍ͭೖΔ͔͸ෆ໌ɺͨͩɺ࢓༷ࡦఆऀ͸΍Δؾ

    View Slide

  87. ·ͩ·ͩଞʹ΋ظ଴͢Δͷ͸
    ͋Δ
    SharedArrayBuffer
    Observable
    bind operator
    etc

    View Slide

  88. ·ͱΊ

    View Slide

  89. ·ͱΊ
    • JavaScript ͸ͲΜͲΜਐԽ͍ͯ͠Δ
    • ಛʹES2015Ͱ͔ͳΓਐԽ͠ɺ᠘͸ݮͬͨ
    • ࠓޙ΋ਐԽͷ଎౓Λ଎Ί͍ͯΔ
    • ಛʹ։ൃऀͱ࢓༷ࡦఆऀͷ͕ؒॖ·͖ͬͯͨ
    • JavaScript Λࠓޙྑ͍ͯ͘͘͠ͷ͸๻Β

    View Slide

  90. ͋Γ͕ͱ͏͍͟͝·ͨ͠ɻ
    ͔͝͠·࠷ߴ

    View Slide