Share
Embed
Transcript
52 slides
-
Array.prototype.includes • ྻʹཁૉؚ͕·ΕΔ͔Ͳ͏͔͕ఆͰ͖Δ const array = ['a', 'b', 'c']; array.includes('a');
// true array.includes('c'); // true array.includes('d'); // false -
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 ༗ͬͨΑʂ'); } -
Exponentiation Operator • ྦྷͷԋࢉࢠ͕૿͑ͨΑʂ 2 ** 2 // 4 2
** 3 // 8 // before ES2015 Math.pow(2, 2) Math.pow(2, 3) -
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 -
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ΑΓҾ༻ -
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; } -
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"); } -
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'] -
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"] -
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]); }); -
Object.entries • Ҿʹ༩͑ͨΦϒδΣΫτ͕ॴ༗͢Δɺྻڍ ՄೳͳϓϩύςΟͷ [key, value] ͷྻΛฦ ͢ • ॱ൪
for ... in … ϧʔϓͷ࣮ߦॱͱҰॹ const obj = {hoge: 'a', fuga: 'b'}; console.log(Object.entries(obj)); // Array(2) [["hoge", "a"], ["fuga", "b"]] -
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"} -
Object.getOwnPropertyDescr iptors • ΦϒδΣΫτͷͯ͢ͷϓϩύςΟσΟεΫϦ ϓλΛؚΉΦϒδΣΫτΛฦ͢ ଐੑ ҙຯ 8SJUBCMF Λॻ͖ࠐΈՄೳ͔ &OVNFSBCMF
ྻڍՄೳ͔ʢGPSJOͱ͔Ͱରʹ͢Δ͔ʣ $POpHVSBCMF %FTDSJQUPSΛมߋՄೳ͔ 7BMVF (FU (FUUFS 4FU 4FUUFS -
Trailing commas in function parameter lists and calls • ҾΛෳߦͰॻ͍ͨͱ͖ʹɺ͍ΘΏΔέπ
ΧϯϚΛڐ༰ function hoge( param1, param2, // <-- OK ) { return null; } hoge( "foo", "bar", // <-- OK ) -
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; } -
async function add1(10).then(v => { console.log(v); // 4ඵޙʹ60Λදࣔ͢Δ }); add2(10).then(v
=> { console.log(v); // 2ඵޙʹ60Λදࣔ͢Δ }); -
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]; }); } -
await ࣜʹ͍ͭͯ • awaitasync functionͷ࣮ߦΛҰ࣌ఀࢭͯ͠ɺpromiseͷղ ܾΛͭ • awaitͱ͕ͨ͠promiseͰͳ͍߹ɺΛղܾ͞Εͨ promiseʹมͯ͠ɺͦΕΛͭ •
awaitasyncؔͷதͳΒɺPromise.Allͱ͔ͬͯ͘ ΕΔɻ • awaitͷΤϥʔॲཧtry/catchͱawait/catch͕ར༻Ͱ͖Δɻ -
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! -
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 ͕දࣔ͞ΕΔ -
Shared memory and atomics • SharedArrayBuffer • Atomics • WorkerؒͰΛڞ༗͢Δ͜ͱ͕Ͱ͖Δํ๏ͷҰͭ
• ࠓ·ͰpostMessageͰΛΓͱΓ͍ͯͨ͠ • ϚϧνεϨουͰॲཧΛ͢Δ߹ʹɺmessage ͘ɺεϨουؒͰσʔλΛίϐʔ͢Δखஈͱͯ͠໘ -
// 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ؒͰσʔλΛڞ༗͢Δ -
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ؒͰσʔλΛڞ༗͢Δ -
Shared memory and atomics • SharedArrayBufferɺਫ਼ͷߴ͍λΠϚʔͱ ͯ͠αΠυνϟωϧ߈ܸʹར༻Ͱ͖ͯ͠·͏ • https://security.stackexchange.com/ questions/177033/how-can-
sharedarraybuffer-be-used-for-timing- attacks -
ઢɿྻڍՄೳͱॴ༗ͱʁ • MDN web docs: Enumerability and ownership of properties
• ίʔυͰද͢ͱɺ hasOwnProperty() === true && propertyIsEnumerable() === true -
ྻڍՄೳ const obj = {'hoge': 'a'}; // Object.definePropertyͰՃ͞ΕͨϓϩύςΟ // enumerable͕σϑΥϧτͰfalse
Object.defineProperty(obj, 'fuga', {value: 'b'}); console.log(Object.values(obj)); // [‘a’] // ྻڍՄೳͳϓϩύςΟͷόϦϡʔͷΈ -
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 // ॴ༗ͯ͠ͳ͍ϓϩύςΟͷόϦϡʔग़ͳ͍ ॴ༗ -
ઢɿSpectre ʹ͍ͭͯ • ਤղͰΘ͔ΔSpectreͱMeltdown by Satoru Takeuchi • SpectreBusters͋Δ͍Linuxʹ͓͚Δ
Spectreରࡦ by Masami Hiramatsu