Skip to content

Instantly share code, notes, and snippets.

@jeancochrane
Created March 26, 2019 00:40
Show Gist options
  • Save jeancochrane/ffb46a000af191eff580c94ca0786555 to your computer and use it in GitHub Desktop.
Save jeancochrane/ffb46a000af191eff580c94ca0786555 to your computer and use it in GitHub Desktop.

Modern JavaScript: A (Brief) Overview

Lunch&Learn | 2019-03-26

What's new in modern JavaScript?

Modules

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))

Classes

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)

Constants

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

Arrow functions

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)
})

Parameter handling

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

Iterators

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)
}

Template literals

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!`

Promises

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`)
})

async/await

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

Further reading

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment