Lunch&Learn | 2019-03-26
To make a module's (i.e. a script's) methods or variables useable by another module, export them:
// lib/math.js
export function sum (x, y) { return x + y }
export var pi = 3.141593
// someApp.js
import { sum, pi } from "lib/math"
console.log("2π = " + sum(pi, pi))
Use wildcards and aliases to import entire modules:
// otherApp.js
import * as math from "lib/math"
console.log("2π = " + math.sum(math.pi, math.pi))
Support for real OOP-style classes:
class Shape {
constructor (x, y) {
this.move(x, y)
}
move (x, y) {
this.x = x
this.y = y
}
}
Inheritance works as you'd expect:
class Rectangle extends Shape {
constructor (x, y, width, height) {
super(x, y)
this.width = width
this.height = height
}
}
Instantiate classes with the new keyword:
var r = new Rectangle(50, 20, 10, 10)
Support for mutable and immutable variables:
// PI will be immutable
const PI = 3.141593
// x will be mutable
let x = 10
x += 1
x === 11
More succinct closure syntax for expressions:
odds = evens.map(v => v + 1)
Arrow functions can be used in statements, too:
nums.forEach(v => {
if (v % 5 === 0)
fives.push(v)
})
Arrow functions have the useful property that they don't reassign this
in
the function body:
this.nums.forEach((v) => {
if (v % 5 === 0)
this.fives.push(v)
})
Functions can now have default parameters:
function f (x, y=7, z=42) {
return x + y + z
}
f(1) === 50
Functions can also aggregate variable numbers of arguments into a single parameter:
function f (x, y, ...a) {
return (x + y) * a.length
}
f(1, 2, "hello", true, 7) === 9
Support for generators:
function* fibonacci () {
let pre = 0, cur = 1
while true {
[ pre, cur ] = [ cur, pre + cur ]
yield cur
}
}
New short syntax for iterating over all values in an iterable:
for (let n of fibonacci) {
if (n > 1000)
break
console.log(n)
}
Simpler syntax for templating variables in strings, reminiscent of Python 3.6's f-strings:
const customer = { name: "Foo" }
const card = { amount: 7, product: "Bar", unitprice: 42 }
let message = `Hello ${customer.name}, want to buy ${card.amount} ${card.product}?`
message += ` It'll cost you a total of ${card.amount * card.unitprice} bucks!`
Representation of a value that may be made asynchronously available in the future:
function msgAfterTimeout (msg, who, timeout) {
return new Promise((resolve, reject) => {
setTimeout(() => resolve(`${msg} Hello ${who}!`), timeout)
})
}
Use the methods then()
, catch()
, and finally()
to fulfill the promise:
msgAfterTimeout("", "Foo", 100).then((msg) => {
console.log(msg)
}).catch((err) => {
console.log(`Something went wrong: ${err}`)
}).finally((msg) => {
console.log(`done after 100ms`)
})
Use the async
keyword to automatically return a promise from a function:
async function f() {
return 1;
}
f().then((val) => { console.log(val) }); // 1
Inside async functions (and only inside async functions) use the await
keyword
to block execution and resolve promises:
async function f() {
let promise = new Promise((resolve, reject) => {
setTimeout(() => resolve("done!"), 1000)
});
let result = await promise; // wait till the promise resolves (this will block execution)
console.log(result); // "done!"
}
Use standard exceptions to reject promises in async functions:
async function f() {
let response = await fetch('http://no-such-url');
}
// f() becomes a rejected promise
f().catch((msg) => { console.log(msg) }); // TypeError: failed to fetch
- ES6 New Features: Overview & Comparison
- Provides good comparisons with ES5 syntax. I cribbed most of my examples from this guide.
- ES6 Promises
- Quick, easy-to-grok blog post about promises.
- Async/await
- A detailed guide to the
async
/await
synatx.
- A detailed guide to the
- What's new in ES2018?
- JavaScript continues to evolve; look at all these features!