ES2015の現在とESNextの未来

 ES2015の現在とESNextの未来

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

D76231a2114896dfcc7b79ac69558b79?s=128

Yosuke Furukawa

June 11, 2016
Tweet

Transcript

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

  2. Twitter: @yosuke_furukawa Github: yosuke-furukawa

  3. ࠷ۙ

  4. None
  5. ࡱӨ͞Εͨসإ

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

  7. JavaScript

  8. None
  9. None
  10. None
  11. JavaScript is the world’s most misunderstood Programming Language — Douglas

    Crockford
  12. JavaScript Trap Examples

  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();
  14. JavaScript Traps 1 var test = 'global'; function foo() {

    console.log(test); // undefined if (true) { var test = 'local'; console.log(test); // local } } foo();
  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ͷ ղऍ͸͜͏ͳΔ
  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(); ר্͖͛ࣄނ
  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();
  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();
  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͕ࢦ͍ͯ͠Δ΋ͷ͕ มΘΔ
  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
  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); });
  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
  23. None
  24. ES2015

  25. ES2015ʁ • JavaScript ͷ৽͍͠ *ن֨* • ਖ਼໊ࣜশ͸ ECMA-262 • ௨শ

    ECMAScript • ECMA International ஂମ͕ఆٛ • ͋͘·Ͱن֨Ͱ࣮͋ͬͯ૷Ͱ͸ͳ͍
  26. ES6? ES7? • ECMA-262(௨শ ECMAScript) 6th Edition ͳ ͷͰ ES6

    • ࠓ೥͸ ES7 • ͨͩ΋͏͜ͷݺশ͸ͦΜͳසൟʹ࢖Θͳ͍ • ৄ͘͠͸ޙͰઆ໌͢Δ
  27. ES2015 ͸͖ͬ͞ͷ᠘Λճආ ͢ΔͨΊͷ๷۩

  28. avoid traps using ES2015

  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(); ר্͖͛ࣄނ
  30. Use let or const

  31. JavaScript Traps 1 const test = 'global'; function foo() {

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

    console.log(test); // global if (true) { const test = 'local'; console.log(test); // local } } foo(); LGTM
  33. let ͱ const • block scope ͱݴͬͯม਺είʔϓ͕ϒϨʔε{}ͷதʹ ด͡Δ • let

    ͸࠶୅ೖՄೳͳม਺ • const ͸࠶୅ೖෆՄೳͳม਺ • جຊతʹ͸ const Λ࢖ͬͯ let ͸୅ೖՄೳͳ΋ͷʹͷ Έ࢖͏ͷ͕ίʔυϚφʔʹͳΓͭͭ͋Δ
  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
  35. Use arrow function

  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();
  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
  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);
  39. ͍ͭͰʹ֮͑Α͏ class

  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
  41. class • JavaScript Ͱ class Λ࡞ΕΔΑ͏ʹͳͬͨ • ͜Ε·Ͱͷ prototype ͷԆ௕

    • ܧঝͱ͔΋Մೳ class Alice extends Person { }
  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
  43. Use Promise

  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); });
  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
  46. Promise • ඇಉظॲཧͷݺͼग़͠Λந৅Խͨ͠΋ͷ • then Ͱ੒ޭ࣌ͷݺͼग़͠ɺ catch Ͱࣦഊ࣌ͷྫ֎͕औ ಘͰ͖Δ •

    then Ͱܨ͙͜ͱͰ callback hell Λճආ͢Δ • ※NodeͷAPI͸·ͩPromiseʹͳͬͯͳ͍ͷͰผ్ PromiseԽ͢Δॲཧ(Promisify) ͕ඞཁ
  47. ͍ͭͰʹ֮͑Α͏ generator/yield

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

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

  51. ࠓ࢖͑Δͷʁʁʁ

  52. Yes and No

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

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

  55. Ͱ΋ɾɾɾ • ϒϥ΢β͝ͱʹ࢖͑Δػೳ͕όϥόϥ • Node.js ΋όʔδϣϯʹΑͬͯ͸࢖͑ͳ͔ͬͨ Γ΋͢Δ • ಛʹ ES

    Modules ͸EdgeҎ֎ͩͱ࢖͑ͳ͍ • transpiler Λ࢖͏ͱIEͱ͔Ͱ΋ಈ͘Α͏ʹͳΔ
  56. Transpiler

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

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

  59. tower-of-babel

  60. ESNext

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

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

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

    ECMAScript ͷ࣍ͷ೥ ࣍ʹ௥Ճ͞ΕΔɻ
  64. feature based release • Web ͷਐԽ͸଎͍ • ES2015͸࢓༷ࡦఆ·ͰʹԿ೥΋͔͔͍ͬͯΔ • ਐԽʹద༻͢ΔͨΊʹ೥࣍Ͱߋ৽

    • ػೳϕʔεͰܾ·͍ͬͯ͘
  65. ESNextظ଴ageͷػೳୡ

  66. async-await

  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); });
  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); }); ·ͩͪΐͬͱඍົ ओʹ͜ͷล
  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); });
  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
  71. async-await • generator/yield Ͱ΍Δͷ͸एׯϋοΩʔ • generator/yield ͸܁Γฦ͠ՄೳͳΦϒδΣΫτͷੜ ੒ͱૢ࡞ʹಛԽͤͯ͞ɺඇಉظॲཧ͸ઐ༻ͷߏจΛ༻ ҙ͢Δ •

    async-await Ͱॻ͘ͱ*/yield ΑΓ͸ݟ௨͕͠ྑ͍ • དྷ೥ͷ ES2017 Ͱ͸ೖΔՄೳੑ͕ߴ͍
  72. SIMD

  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; i<a.length; i++) { c[i] = a[i] + b[i]; } console.log(c); // 6, 8, 10, 12 •
  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!
  75. SIMD • JavaScript ͰϕΫτϧܭࢉΛ؆୯͔ͭߴ଎ʹ ߦΘͤΔΑ͏ʹ͢ΔͨΊͷ΋ͷ • Ԡ༻ྫɿػցֶशɺը૾ॲཧɺ෺ཧԋࢉɺ3D άϥϑΟοΫε etc •

    ES2017 ͰೖΔ͔΋ɾɾɾ
  76. class props declarations

  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 ʹهड़ ͠ͳ͍ͱ͍͚ͳ͍
  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();
  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
  80. class props declarations • class Ͱ௚઀member/static member Λॻ͚Δ Α͏ʹ͠Α͏ͱ͍͏΋ͷɻ •

    ಛʹ static member ͸ React ͱ͔Ͱ΋Α͘ར ༻͢ΔͷͰॻ͚Δͱخ͍͠ɻ • ͍ͭೖΔ͔͸ෆ໌ɺೖΒͳ͍Մೳੑ΋͋Δɻ
  81. ͍ͭͰʹ֮͑Α͏ private field

  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(); ‧‪‬‭⛺è('ω')è⛺䡡‬‪‧
  83. private member field • classʹ private memberΛॻ͚ΔΑ͏ʹ͠Α͏ • #foo ͱ͔Ͱఆٛ

    • ͍ͭೖΔ͔͸ෆ໌ɺೖΒͳ͍Մೳੑ΋͋Δɻ
  84. ͍ͭͰʹ֮͑Α͏ Decorator

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

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

  88. ·ͱΊ

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

    • JavaScript Λࠓޙྑ͍ͯ͘͘͠ͷ͸๻Β
  90. ͋Γ͕ͱ͏͍͟͝·ͨ͠ɻ ͔͝͠·࠷ߴ